<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ best practices - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ best practices - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 18 May 2026 22:34:42 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/best-practices/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How AI Changed the Economics of Writing Clean Code ]]>
                </title>
                <description>
                    <![CDATA[ If you've ever wanted to add an interface to a codebase and gotten pushback, you already know the argument: "That's twice the code for the same thing." And honestly? It was a fair point. You'd write t ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-ai-changed-the-economics-of-writing-clean-code/</link>
                <guid isPermaLink="false">69f0bce210a70b3335bf635a</guid>
                
                    <category>
                        <![CDATA[ Software Engineering ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Code Quality ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Aaron Yong ]]>
                </dc:creator>
                <pubDate>Tue, 28 Apr 2026 13:57:54 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/ecb13bda-70dd-437a-8d9a-4ef8b18ccc05.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>If you've ever wanted to add an interface to a codebase and gotten pushback, you already know the argument: "That's twice the code for the same thing."</p>
<p>And honestly? It was a fair point. You'd write the contract — the interface, the abstract class, the protocol — and then write the implementation. Two files where one would do. That's more surface area, more indirection, and more to maintain.</p>
<p>The Ruby and Rails communities built an entire philosophy around this: convention over configuration, less ceremony, fewer keystrokes. If the framework could infer your intent, why spell it out?</p>
<p>Then AI happened.</p>
<p>I was recently chatting with a CEO about what current-generation software engineers get wrong, and he put it cleanly:</p>
<blockquote>
<p>"Abstract interfaces were challenging a few months ago just because it required twice as much code. But with AI, lines of code are free. The reason we still need such constructs is because at some point a human still needs to look at the code. Interfaces reduce the cognitive load."</p>
</blockquote>
<p>That framing stuck with me. The cost of writing code has collapsed. The cost of reading it hasn't moved. And that asymmetry changes everything about how you should think about abstraction.</p>
<p>Here's what I mean.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-your-brain-is-the-bottleneck">Your Brain Is the Bottleneck</a></p>
</li>
<li><p><a href="#heading-the-greats-already-knew-this">The Greats Already Knew This</a></p>
</li>
<li><p><a href="#heading-the-economics-have-flipped">The Economics Have Flipped</a></p>
</li>
<li><p><a href="#heading-the-data-backs-it-up">The Data Backs It Up</a></p>
</li>
<li><p><a href="#heading-the-contrarian-case-and-why-it-actually-agrees">The Contrarian Case (And Why It Actually Agrees)</a></p>
</li>
<li><p><a href="#heading-what-this-means-for-you">What This Means for You</a></p>
</li>
<li><p><a href="#heading-references">References</a></p>
</li>
</ul>
<h2 id="heading-your-brain-is-the-bottleneck">Your Brain Is the Bottleneck</h2>
<p>This isn't a vibes argument. There's actual neuroscience behind why interfaces help.</p>
<p>In 1988, educational psychologist John Sweller introduced Cognitive Load Theory. A <a href="https://dl.acm.org/doi/full/10.1145/3483843">2022 ACM review</a> covers how it's been applied to computing education since.</p>
<p>The short version: your brain juggles three types of load when processing information. <em>Intrinsic</em> load is the inherent difficulty of the problem itself. <em>Extraneous</em> load is the noise — poorly organized information, unnecessary details, bad naming. <em>Germane</em> load is the good stuff — the mental effort you spend building useful mental models.</p>
<p>Here's the kicker: your working memory can only hold a handful of chunks of information at a time — cognitive scientists typically estimate somewhere between 2 and 6. Not 2 to 6 files, or 2 to 6 classes — 2 to 6 <em>things</em>.</p>
<p>Felienne Hermans explores this in <em>The Programmer's Brain</em> (2021), arguing that design patterns act as chunking aids. When you recognize a Strategy pattern, your brain collapses an entire class hierarchy into a single cognitive unit. The word "Strategy" replaces five classes and their relationships. That's not hand-waving about clean code — that's how human memory actually works.</p>
<p>And we can literally see it on brain scans. In 2021, a team led by Norman Peitek and Janet Siegmund published <a href="https://dl.acm.org/doi/10.1109/ICSE43902.2021.00056">an fMRI study on program comprehension</a> that won the ACM SIGSOFT Distinguished Paper Award at ICSE.</p>
<p>They put developers in brain scanners and watched what happened when they read code. The finding: semantic-level comprehension — understanding <em>what</em> code does — required measurably less neural activation than bottom-up syntactic parsing — tracing <em>how</em> it does it.</p>
<p>An interface lets you comprehend at the semantic level. <code>UserRepository.findById(id)</code> tells you everything you need to know without opening the implementation. Your brain doesn't need to hold the SQL query, the connection pool logic, the error handling, and the result mapping in working memory simultaneously. The interface compresses all of that into one chunk.</p>
<p>That's not elegance. That's neuroscience.</p>
<h2 id="heading-the-greats-already-knew-this">The Greats Already Knew This</h2>
<p>The case for abstraction isn't new. The people who built the foundations of computer science were making this argument before most of us were born.</p>
<p>Dijkstra said it with precision:</p>
<blockquote>
<p><em>"The purpose of abstracting is not to be vague, but to create a new semantic level in which one can be absolutely precise."</em></p>
</blockquote>
<p>Abstraction isn't about hiding things from people who can't handle complexity. It's about creating a level of discourse where you can reason clearly.</p>
<p>David Parnas formalized information hiding in his <a href="https://dl.acm.org/doi/10.1145/361598.361623">1972 ACM paper</a>: <em>"Every module is characterized by its knowledge of a design decision which it hides from all others."</em> He proved that decomposing systems by design decisions (rather than processing steps) produced modules that were both more flexible <em>and</em> easier to understand. Comprehensibility wasn't a bonus — it was the design criterion.</p>
<p>Tony Hoare argued that abstraction is the most powerful tool available to the human intellect — a way to manage complexity by focusing on what matters and ignoring what doesn't. Martin Fowler brought it down to earth:</p>
<blockquote>
<p><em>"Any fool can write code that a computer can understand. Good programmers write code that humans can understand."</em></p>
</blockquote>
<p>And then there's John Ousterhout, whose book <em>A Philosophy of Software Design</em> (2018) makes the connection to cognitive load explicit. His central argument: more lines of code can actually be <em>simpler</em> if they reduce cognitive load.</p>
<p>His concept of <em>deep modules</em> — simple interfaces hiding complex implementations — is essentially the argument that interfaces are worth their weight in code. The Unix file system API (<code>open</code>, <code>close</code>, <code>read</code>, <code>write</code>, <code>lseek</code>) is five functions hiding an enormous amount of complexity. That's a deep module. That's the goal.</p>
<p>The Gang of Four put it first in their book for a reason. Page one: <em>"Program to an interface, not an implementation."</em></p>
<p>None of this is controversial. But it's easy to forget when your AI tool just generated 200 lines of perfectly functional inline code in three seconds.</p>
<h2 id="heading-the-economics-have-flipped">The Economics Have Flipped</h2>
<p>Here's where the CEO's insight becomes an economic argument.</p>
<p>The historical case against interfaces was always about <em>writing cost</em>. Interfaces meant more code to write, more files to create, more boilerplate to maintain. The entire dynamic typing movement — Python, Ruby, JavaScript — was partly a reaction to the ceremony that languages like Java imposed. Convention over configuration. Don't Repeat Yourself. Less is more.</p>
<p>But ask yourself: what exactly is the cost of writing boilerplate now?</p>
<p>GitHub's <a href="https://arxiv.org/abs/2302.06590">2022 controlled study</a> found that developers using Copilot completed tasks 55% faster. The boilerplate that used to justify skipping interfaces — the extra file, the type definitions, the method signatures — takes seconds to generate. The writing cost of an interface has effectively collapsed to zero.</p>
<p>But again, the reading cost hasn't budged.</p>
<p>Robert C. Martin argued in <em>Clean Code</em> (2008) that developers spend far more time reading code than writing it — an observation he framed as a ratio of 10 to 1.</p>
<p>You can quibble with the exact number (it's anecdotal), but the direction is consistent across studies. A <a href="https://ieeexplore.ieee.org/document/7997917/">large-scale field study</a> tracking 78 professional developers across 3,148 working hours found they spend roughly 58% of their time on program comprehension alone. New developer onboarding averages six weeks — most of which is spent understanding existing systems, not producing new ones.</p>
<p>Addy Osmani named this asymmetry perfectly. In a <a href="https://addyosmani.com/blog/comprehension-debt/">March 2026 piece</a>, he described <em>comprehension debt</em>:</p>
<blockquote>
<p>"When a developer on your team writes code, the human review process has always been a bottleneck — but a productive and educational one. Reading their PR forces comprehension. AI-generated code breaks that feedback loop. The volume is too high."</p>
</blockquote>
<p>The output looks clean, passes linting, follows conventions — precisely the signals that historically triggered merge confidence. But comprehension debt is distinct from technical debt because it accumulates invisibly — your velocity metrics, your DORA scores, your PR counts all look fine while your team's actual understanding of the codebase quietly erodes.</p>
<p>So here's the math: AI reduced the cost of writing abstractions to near zero. The cost of <em>not</em> having them — in human reading time, onboarding friction, and comprehension debt — hasn't changed at all. The break-even point for "is this interface worth it?" just shifted massively in favor of "yes."</p>
<h2 id="heading-the-data-backs-it-up">The Data Backs It Up</h2>
<p>This isn't theoretical. We have data on what happens when AI generates code without good abstractions.</p>
<p><a href="https://www.gitclear.com/ai_assistant_code_quality_2025_research">GitClear analyzed 211 million changed lines of code</a> between 2020 and 2024. Their findings: code churn — lines reverted or updated within two weeks — doubled compared to the pre-AI baseline. Copy-pasted code blocks rose from 8.3% to 12.3%. And refactoring-associated changes dropped from 25% to under 10%.</p>
<p>AI-generated code, as they put it, "resembles an itinerant contributor, prone to violate the DRY-ness of the repos visited."</p>
<p>The <a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/">METR study</a> (2025) found something even more striking. Experienced open-source developers <em>predicted</em> AI would make them 24% faster. They <em>perceived</em> being 20% faster while using it. They were actually 19% slower. The perception gap is the story — you <em>feel</em> productive while generating code that creates more work downstream.</p>
<p>And then there's a study from Anthropic (yes, the company that makes Claude — full disclosure). They observed 52 software engineers learning a new library. The AI-assisted group completed tasks at the same speed, but scored <a href="https://arxiv.org/abs/2601.20245">17% lower on comprehension quizzes</a> afterward — 50% versus 67%. The biggest declines were in debugging ability. You can ship code you don't understand. You can't debug code you don't understand.</p>
<p>Kent Beck <a href="https://tidyfirst.substack.com/p/90-of-my-skills-are-now-worth-0">put it bluntly</a>: "The value of 90% of my skills just dropped to $0. The leverage for the remaining 10% went up 1000x." What that remaining 10% is, he leaves deliberately open — but it's hard to read that and not think about system design.</p>
<h2 id="heading-the-contrarian-case-and-why-it-actually-agrees">The Contrarian Case (And Why It Actually Agrees)</h2>
<p>I'd be dishonest if I didn't address the people who argue against abstraction. And some of them are very smart.</p>
<p>Casey Muratori's <a href="https://www.computerenhance.com/p/clean-code-horrible-performance">"Clean Code, Horrible Performance"</a> demonstrated that polymorphism and virtual dispatch can make code 10 to 15 times slower than straightforward procedural alternatives.</p>
<p>His benchmark is real. If you're writing a game engine or a high-frequency trading system, abstract interfaces on your hot path will cost you.</p>
<p>Dan Abramov wrote <a href="https://overreacted.io/goodbye-clean-code/">"Goodbye, Clean Code"</a> after watching a premature abstraction make his codebase harder to modify:</p>
<blockquote>
<p><em>"My code traded the ability to change requirements for reduced duplication, and it was not a good trade."</em></p>
</blockquote>
<p>Sandi Metz <a href="https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction">put it more sharply</a>: <em>"Duplication is far cheaper than the wrong abstraction."</em></p>
<p>And Rich Hickey, in his talk <a href="https://www.infoq.com/presentations/Simple-Made-Easy/">"Simple Made Easy"</a>, draws the critical distinction: <em>simple</em> (not intertwined) is not the same as <em>easy</em> (familiar). Wrong abstractions <em>complect</em> — they braid concerns together rather than separating them.</p>
<p>Here's the thing: none of these are arguments against abstraction. They're arguments against <em>bad</em> abstraction.</p>
<p>Muratori's performance argument applies to hot paths in performance-critical systems — not to your REST API's service layer. Abramov and Metz argue against <em>premature</em> abstraction — pulling patterns out before you understand the domain. And Hickey's entire talk is a case <em>for</em> the right abstractions, the ones that genuinely decompose rather than complect.</p>
<p>The irony is that in an AI-assisted world, these arguments are <em>easier</em> to address. You can generate the explicit, unabstracted version first. Let it stabilize. Watch the patterns emerge. Then extract the abstraction — with AI handling the mechanical refactoring. The cost of the "duplicate first, abstract later" approach just dropped to near zero.</p>
<h2 id="heading-what-this-means-for-you">What This Means for You</h2>
<p>If you're writing code with AI tools — and at this point, <a href="https://survey.stackoverflow.co/2024/ai">most of us are</a> — the temptation is to let the AI produce whatever it produces and move on. It works. It passes the tests. Ship it.</p>
<p>But "it works" is table stakes. The harder question is: can the next person who opens this code understand it in under five minutes? Can <em>you</em> understand it in six months?</p>
<p>Interfaces aren't about making code prettier or satisfying some abstract (pun intended) design principle. They're compression algorithms for human cognition. They let your brain operate at the semantic level instead of the syntactic level. And now that AI has eliminated the only real cost of creating them — the boilerplate — there's no economic argument left for skipping them.</p>
<p>The rules haven't changed. The excuse has just expired.</p>
<h2 id="heading-references">References</h2>
<h3 id="heading-academic-papers">Academic Papers</h3>
<ul>
<li><p>Duran, R., Zavgorodniaia, A., &amp; Sorva, J. (2022). <a href="https://dl.acm.org/doi/full/10.1145/3483843">"Cognitive Load Theory in Computing Education Research: A Review."</a> <em>ACM Transactions on Computing Education, 22</em>(4), Article 40.</p>
</li>
<li><p>Parnas, D.L. (1972). <a href="https://dl.acm.org/doi/10.1145/361598.361623">"On the Criteria To Be Used in Decomposing Systems into Modules."</a> <em>Communications of the ACM, 15</em>(12), 1053–1058.</p>
</li>
<li><p>Peitek, N., Apel, S., Parnin, C., Brechmann, A., &amp; Siegmund, J. (2021). <a href="https://dl.acm.org/doi/10.1109/ICSE43902.2021.00056">"Program Comprehension and Code Complexity Metrics: An fMRI Study."</a> <em>ICSE 2021</em>. ACM SIGSOFT Distinguished Paper Award.</p>
</li>
<li><p>Peng, S., Kalliamvakou, E., Cihon, P., &amp; Demirer, M. (2023). <a href="https://arxiv.org/abs/2302.06590">"The Impact of AI on Developer Productivity: Evidence from GitHub Copilot."</a> <em>arXiv:2302.06590</em>.</p>
</li>
<li><p>Shen, J.H. &amp; Tamkin, A. (2026). <a href="https://arxiv.org/abs/2601.20245">"How AI Impacts Skill Formation."</a> <em>arXiv:2601.20245</em>.</p>
</li>
<li><p>Xia, X., Bao, L., Lo, D., Xing, Z., Hassan, A.E., &amp; Li, S. (2018). <a href="https://ieeexplore.ieee.org/document/7997917/">"Measuring Program Comprehension: A Large-Scale Field Study with Professionals."</a> <em>IEEE Transactions on Software Engineering, 44</em>(10), 951–976.</p>
</li>
<li><p>METR. (2025). <a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/">"Measuring the Impact of Early 2025 AI on Experienced Open Source Developer Productivity."</a> <em>metr.org</em>.</p>
</li>
</ul>
<h3 id="heading-talks-and-blog-posts">Talks and Blog Posts</h3>
<ul>
<li><p>Hickey, R. (2011). <a href="https://www.infoq.com/presentations/Simple-Made-Easy/">"Simple Made Easy."</a> <em>Strange Loop Conference</em>.</p>
</li>
<li><p>Beck, K. (2023). <a href="https://tidyfirst.substack.com/p/90-of-my-skills-are-now-worth-0">"90% of My Skills Are Now Worth $0."</a> <em>Tidy First? Substack</em>.</p>
</li>
<li><p>Osmani, A. (2026). <a href="https://addyosmani.com/blog/comprehension-debt/">"Comprehension Debt: The Hidden Cost of AI-Generated Code."</a> <em>addyosmani.com</em>.</p>
</li>
<li><p>Muratori, C. (2023). <a href="https://www.computerenhance.com/p/clean-code-horrible-performance">"Clean Code, Horrible Performance."</a> <em>Computer Enhance</em>.</p>
</li>
<li><p>Abramov, D. (2020). <a href="https://overreacted.io/goodbye-clean-code/">"Goodbye, Clean Code."</a> <em>overreacted.io</em>.</p>
</li>
<li><p>Metz, S. (2016). <a href="https://sandimetz.com/blog/2016/1/20/the-wrong-abstraction">"The Wrong Abstraction."</a> <em>sandimetz.com</em>.</p>
</li>
<li><p>GitClear. (2025). <a href="https://www.gitclear.com/ai_assistant_code_quality_2025_research">"AI Assistant Code Quality in 2025."</a> <em>gitclear.com</em>.</p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Protect Your GitHub Repos Against Malicious Clones ]]>
                </title>
                <description>
                    <![CDATA[ The world of open-source development comes with various cyber threats. GitHub is still facing a type of attack that is ongoing since last year where attackers mirrored a huge number of repositories. So as it turns out…the clone wars are not over! If ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/protect-github-repos-from-malicious-clones/</link>
                <guid isPermaLink="false">68781639d48174ae283f8a5b</guid>
                
                    <category>
                        <![CDATA[ repo confusion ]]>
                    </category>
                
                    <category>
                        <![CDATA[ repository confusion ]]>
                    </category>
                
                    <category>
                        <![CDATA[ fake repos ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ clone ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ #cybersecurity ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Malware ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Supply Chain Attack ]]>
                    </category>
                
                    <category>
                        <![CDATA[ malicious ]]>
                    </category>
                
                    <category>
                        <![CDATA[ checklist ]]>
                    </category>
                
                    <category>
                        <![CDATA[ phishing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ infostealer ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Prevention ]]>
                    </category>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ brooklyn ]]>
                </dc:creator>
                <pubDate>Wed, 16 Jul 2025 21:14:33 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1752700407765/5fe06816-3d3a-40e4-8a4e-5cfe96a22368.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The world of open-source development comes with various cyber threats. GitHub is still facing a type of attack that is ongoing since last year where attackers mirrored a huge number of repositories. So as it turns out…the clone wars are not over!</p>
<p>If you haven’t heard about what’s going on:</p>
<blockquote>
<p>GitHub is struggling to contain an ongoing attack that’s flooding the site with with millions of code repositories. These repositories contain obfuscated malware that steals passwords and cryptocurrency from developer devices. … The result is millions of forks with names identical to the original one.</p>
<p>– Dan Goodin, <a target="_blank" href="https://arstechnica.com/security/2024/02/github-besieged-by-millions-of-malicious-repositories-in-ongoing-attack/">Ars technica</a></p>
</blockquote>
<p>Because search engines and GitHub’s own search rankings favor recent activity, these cloned repositories often float to the top – then they lure unsuspecting developers into pulling code that may contain malware.</p>
<p>One of my <a target="_blank" href="http://github.com/brooks-code/miniature-fortnight">repositories</a> has been targeted by such an attack, prompting me to monitor it closely. This guide offers tips to spot malicious repository clones before they catch you off guard.</p>
<h2 id="heading-table-of-contents"><strong>Table of Contents</strong></h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-what-is-a-repository-confusion-attack">What is a Repository Confusion Attack?</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-supply-chain-attacks">Supply Chain Attacks</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-basic-mitigation-strategies">🛡️ Basic Mitigation Strategies</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-verify-the-contributors-profiles">Verify the contributors profiles</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-search-for-clone-repositories">Search for clone repositories</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-examine-the-commit-pattern">Examine the commit pattern</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-examine-the-commit-history">Examine the commit history</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-examine-the-commit-contents">Examine the commit contents</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-compare-the-concerned-files">Compare the concerned files</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-some-information-about-the-malware">Some information about the malware</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-action-time">Action Time</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-more-resources">More Resources</a></p>
</li>
</ol>
<h2 id="heading-what-is-a-repository-confusion-attack"><strong>What is a Repository Confusion Attack?</strong></h2>
<p>A repository confusion attack involves:</p>
<ul>
<li><p>Cloning legitimate repositories.</p>
</li>
<li><p>Injecting malicious code into the clone.</p>
</li>
<li><p>Uploading the clone.</p>
</li>
<li><p>Spreading through various unaware actors.</p>
</li>
</ul>
<h3 id="heading-supply-chain-attacks"><strong>Supply Chain Attacks</strong></h3>
<p>If you search for repository confusion on the internet, you'll find out it's a type of <em>supply chain attack</em>.</p>
<p>A supply chain attack is an <em>indirect</em> threat where hackers try infiltrating a system by targeting a trusted third-party or software component, rather than attacking the primary target directly.</p>
<p>It's not the first time this has happened. Before GitHub was targeted, PyPI was attacked in 2023 with <a target="_blank" href="https://arstechnica.com/information-technology/2023/01/more-malicious-packages-posted-to-online-repository-this-time-its-pypi/">fake packages</a> posing as legitimate. These packages lured negligent pip users into downloading malicious payloads (containing in most cases <a target="_blank" href="https://en.wikipedia.org/wiki/Infostealer">infostealer malware</a>).</p>
<h2 id="heading-basic-mitigation-strategies"><strong>🛡️ Basic Mitigation Strategies</strong></h2>
<p><strong>Before</strong> using any repository, make sure you follow these steps and take these precautions.</p>
<h3 id="heading-verify-the-contributors-profiles"><strong>Verify the contributors profiles</strong></h3>
<p>That's a first check: if you see a rather empty GitHub profile – one without reputation that contains just one repository but with a lot of daily commits to it – well, that's a bit suspicious.</p>
<p>In the fake repository, the original author will be listed as a contributor, too. Check that profile. You should be able to find the legitimate repository and do some comparisons.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752335573817/c39aca11-2605-47a2-8a6b-aded16547783.png" alt="GitHub screenshot of a repository contributors" width="316" height="156" loading="lazy"></p>
<p>In the above screenshot you can see solotech143, my evil doppelgänger <em>(he’s been taken down since)</em>.</p>
<h3 id="heading-search-for-clone-repositories"><strong>Search for clone repositories</strong></h3>
<p>You can do a GitHub search by repository name and sort the results by most recent first. Malicious repositories tend to appear at the top of the search results because they are updated more frequently. The original repository might be hidden deeper in the search results.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752335785307/943c6dd3-aa28-4d72-b63a-65736de06dcf.png" alt="GitHub clone search results." width="1172" height="314" loading="lazy"></p>
<p>It’s like clone wars.</p>
<p><strong>This is where it’s dangerous:</strong> users generally click on the first few search results, and in that type of attack, you’re almost guaranteed to see the attacker’s fake repository at the top of the results. The attacker achieves that by giving the fake repository regular fresh commits (and sometimes even a few stars!).</p>
<p>In my case, the original repository is a submission for the HackaViz 2025 competition. Hackathons offer a good attack surface because, beyond the fact they draw niche communities, they are also time sensitive.</p>
<p>Now, let’s move forward a year and imagine Hackaviz 2026 is starting soon. The attacker has easily outranked the untouched original submission. Which repository is most likely to be visited when future competitors – unaware of the scam – will look for the previous submissions?</p>
<h3 id="heading-examine-the-commit-pattern"><strong>Examine the commit pattern</strong></h3>
<p>Here’s when things take a weird turn. Malicious clones are run by automated agents, so the commit history fits a pattern that is rather unusual for a human. Of course, you can automate for many legitimate reasons but… this will always follow a clear goal and there will always be a human-touch at some point. In this case, commits are not adding up.</p>
<p>Let's see how that looks in the screenshots below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752335872381/1238dee9-3568-4d2b-88bb-f63258ffb045.png" alt="1238dee9-3568-4d2b-88bb-f63258ffb045" width="390" height="197" loading="lazy"></p>
<p>Regular like a clock...</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752335891381/77f835fe-cccf-409f-85d7-789f918d4aa3.png" alt="A GitHub screenshot of a very active contribution activity.." width="764" height="602" loading="lazy"></p>
<p>... and hyperactive!</p>
<h3 id="heading-examine-the-commit-history"><strong>Examine the commit history</strong></h3>
<p>You can’t! And that's the weird part. You're just able to see the last and the initial commit. So why is it hiding all of them? Do you like it when someone hide things from you?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752336385127/6274dd87-0a97-4c38-8849-9d547b9edb22.png" alt="A github commits history screenshot for one day." width="1304" height="225" loading="lazy"></p>
<p>For July 10th, we should be able to see 11 commits, where are the ten others?</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752336355084/4c7c343d-2000-4359-ae98-dcc98fb08732.png" alt="A github commits history screenshot for a whole period." width="1307" height="369" loading="lazy"></p>
<p>Well, you can only check the first and last commit. That is not a lot for a repository that has more than 2000 commits registered.</p>
<h3 id="heading-examine-the-commit-contents"><strong>Examine the commit contents</strong></h3>
<p>Well, since I can always check the last commit, I checked some of them. They share the same pattern: the bot is constantly looping over the README file doing the same modifications. As you can see in the screenshot below, it’s updating the file with links to an infected release.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752336493881/e8b57b4c-4d13-44f8-bca6-bd8fbad2738c.png" alt="A github screenshot of commits to a malicious repository." width="1382" height="800" loading="lazy"></p>
<p>Above you can see an AI agent stuck in the Readme loop of change.</p>
<p>Human edits are more varied. In a human-driven project, you will see a large mix of commits: feature commits, exploratory experiments, bug fixes, styling tweaks, and sometimes reverts. A bot clone will often just overwrite files, bump versions, or re-inject the same malicious payload repeatedly with no real contribution to the codebase.</p>
<h3 id="heading-compare-the-concerned-files"><strong>Compare the concerned files</strong></h3>
<p>This is where common sense comes handy. So, you have two README's:</p>
<ol>
<li><p>The <a target="_blank" href="https://web.archive.org/web/20250711182419/https://github.com/solotech143/miniature-fortnight/blob/main/README.md">first</a> consists of AI-generated content that is cluttered with emojis and low-value information. It is designed solely to entice you into clicking the download link of the release.</p>
</li>
<li><p>The <a target="_blank" href="https://github.com/brooks-code/miniature-fortnight/blob/main/README.md">other</a> follows <a target="_blank" href="https://www.freecodecamp.org/news/how-to-write-a-good-readme-file/">best practices</a> for creating a good README file. It is accurate and well-structured and functions as a valuable helper and explainer to the code. It also goes deep into the most important aspects of the project. This is usually a good sign that a repository is organic and genuine.</p>
</li>
</ol>
<h3 id="heading-some-information-about-the-malware"><strong>Some information about the malware</strong></h3>
<p>What do we have so far? Well, a suspicious link in a phishy, AI-generated README file that is consistent with a very suspicious pattern in the commit history.</p>
<p>Now, let’s have a closer look at that dubious release and let’s see what an online antivirus scanner might reveal about it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752336589656/124aecf2-39e9-4158-9a06-f0fd59cbf8c1.png" alt="A  github screenshot of commits to a malicious repository." width="1216" height="404" loading="lazy"></p>
<p>The malware is packed only in the miniature-fortnight-v1.7.6.zip release.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752336609780/7eaf7fc8-73f2-4d9d-b169-1d5c50ce84f2.png" alt="A malware analysis result." width="1317" height="757" loading="lazy"></p>
<p>Above you can see the result of a scan with an online scanner.</p>
<p>The .zip file contains <strong>only</strong> four files:</p>
<ul>
<li><p>config.txt</p>
</li>
<li><p>launch.bat</p>
</li>
<li><p>lua51.dll</p>
</li>
<li><p>luajit.exe</p>
</li>
</ul>
<p>These files are <strong>totally unrelated</strong> to the source project (a Python data science project with Jupyter notebooks combined to a React app using three.js).</p>
<p>I will not go into the detail in this article. But for the curious ones, it's an infostealer malware (a malware that will exfiltrate your credentials and other precious information about your configuration) similar to the one described in <a target="_blank" href="https://www.trendmicro.com/en_us/research/25/c/ai-assisted-fake-github-repositories.html#">detail here</a>.</p>
<h2 id="heading-action-time"><strong>Action Time</strong></h2>
<p>If you discover a potentially malicious repository, here are some steps you can take:</p>
<ol>
<li><p>Document some evidence.</p>
</li>
<li><p>Notify the original repository maintainers.</p>
</li>
<li><p>Report the malicious clone to GitHub.</p>
</li>
</ol>
<p>Reporting a repository or a profile on GitHub is easy and fast. Go to the user’s profile page, click “Block or report” in the left sidebar and choose “Report abuse” in the pop-up. You will have to complete a short contact form with some details about the behavior before submitting. If needed, you can find more information on <a target="_blank" href="https://docs.github.com/en/communities/maintaining-your-safety-on-github/reporting-abuse-or-spam#reporting-a-user">GitHub</a>.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>This is a description of just one attack, from the perspective of someone who found out that one of his repository had been targeted. There are likely cases of more sophisticated attacks. But the clone repository flood we can see on GitHuB is definitely massive low quality automation. Quantity over quality.<br>To be honest, I'm quite surprised algorithms crafted at GitHub didn't manage to spot this one.</p>
<p>This also raises questions related to AI.</p>
<ul>
<li><p>What happens when LLMs are trained on malicious content? That’s a more general question about <a target="_blank" href="https://arstechnica.com/information-technology/2024/01/ai-poisoning-could-turn-open-models-into-destructive-sleeper-agents-says-anthropic/">AI poisoning</a>.</p>
</li>
<li><p>A human might easily spot the patterns and the low quality content <em>for now</em>. But..</p>
<ul>
<li><p>Imagine you are using coding agents, many of them. Will the agents pick-up the malicious clone instead of the original one? How to distinguish the repositories from an automaton's perspective?</p>
</li>
<li><p>The attackers <strong>will</strong> refine their tactics, making the clones more human-like and therefore luring us more easily into their traps.</p>
</li>
</ul>
</li>
<li><p>This is really a situation that makes me wonder about the early days of Google. Back then, the company had to fight huge amounts of spam due to keyword stuffing and manipulative SEO tactics. Will big tech companies have to go through a <a target="_blank" href="https://en.wikipedia.org/wiki/Timeline_of_Google_Search#Full_timeline">Florida update</a> moment to face the rise of AI generated spam ?</p>
</li>
</ul>
<h2 id="heading-more-resources"><strong>More Resources</strong></h2>
<ul>
<li><p><a target="_blank" href="https://www.trendmicro.com/en_be/research/23/j/infection-techniques-across-supply-chains-and-codebases.html">A detailed description of the attack</a></p>
</li>
<li><p><a target="_blank" href="https://www.cisa.gov/sites/default/files/publications/ESF_SECURING_THE_SOFTWARE_SUPPLY_CHAIN_DEVELOPERS.PDF">Complete safety recommendations</a></p>
</li>
</ul>
<p><strong>Stay Informed, Stay Secure!</strong></p>
<p>A <strong>cheat-sheet</strong> is also available on my <a target="_blank" href="https://github.com/brooks-code/repo-confusion-guard">GitHub</a>. Feel free to contribute to it!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Production-Ready Full Stack Apps with the MERN Stack ]]>
                </title>
                <description>
                    <![CDATA[ As developers, we’re always looking for more efficient tools. The MERN stack (MongoDB, Express.js, React, and Node.js) stands out for its JavaScript-centric nature, offering a unified language across the entire application. In this guide, you'll buil... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-production-ready-full-stack-apps-with-the-mern-stack/</link>
                <guid isPermaLink="false">686bd0446349e98b57ebc099</guid>
                
                    <category>
                        <![CDATA[ full stack ]]>
                    </category>
                
                    <category>
                        <![CDATA[ software development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ clean code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Mohit Menghnani ]]>
                </dc:creator>
                <pubDate>Mon, 07 Jul 2025 13:48:52 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1751502709499/b43b3607-f01b-45c0-9797-75eef92497c6.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>As developers, we’re always looking for more efficient tools. The MERN stack (MongoDB, Express.js, React, and Node.js) stands out for its JavaScript-centric nature, offering a unified language across the entire application.</p>
<p>In this guide, you'll build a complete Task Manager app with user authentication, protected routes, and full CRUD functionality, built with React on the frontend and Express/MongoDB on the backend.</p>
<p>This article will serve as your hands-on, code-first guide to building, securing, and deploying a MERN application, drawing from my own practical experience. Every section has code you can run, and I’ll give concise explanations along the way.</p>
<p>It doesn’t matter if you're just getting started with MERN or looking to level up your architecture and production deployment knowledge – this article is designed to get you from zero to production with confidence.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-tools-amp-tech-stack">Tools &amp; Tech Stack</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-skills-amp-setup">Skills &amp; Setup</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-project-setup-laying-the-groundwork">Project Setup: Laying the Groundwork</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-project-structure">Project Structure</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-code-quality-linting-and-formatting">Code Quality: Linting and Formatting</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-testing-ensuring-robustness">Testing: Ensuring Robustness</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-backend-testing-nodejsexpressjs">Backend Testing (Node.js/Express.js)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-frontend-testing-react-testing-library-cypress">Frontend Testing (React Testing Library + Cypress)</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-the-task-manager">How to Build the Task Manager</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-backend-implementation-nodejsexpressjs">Backend Implementation (Node.js/Express.js)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-frontend-implementation-react">Frontend Implementation (React)</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-deployment-from-localhost-to-live">Deployment: From</a> <a target="_blank" href="http://Localhost">Localhost</a> <a class="post-section-overview" href="#heading-deployment-from-localhost-to-live">to Live</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-backend-deployment-nodejsexpressjs">Backend Deployment (Node.js/Express.js)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-frontend-deployment-react">Frontend Deployment (React)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-database-deployment-mongodb-atlas">Database Deployment (MongoDB Atlas)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-1-env-configuration-example">1. .env Configuration Example</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-2-connect-to-mongodb-in-appjs">2. Connect to MongoDB in app.js</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-other-deployment-options">Other Deployment Options</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-security-best-practices-fortifying-your-application">Security Best Practices: Fortifying Your Application</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-setup-input-validation-and-sanitization">Setup Input Validation and Sanitization</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-add-authentication-and-authorization">Add Authentication and Authorization</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-implement-rate-limiting">Implement Rate Limiting</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-setup-cors-configuration-cross-origin-resource-sharing">Setup CORS Configuration (Cross-Origin Resource Sharing)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-use-environment-variables">Use Environment Variables</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-monitoring-and-logging-with-winston-and-morgan">Monitoring and Logging with Winston and Morgan</a></p>
<ul>
<li><a class="post-section-overview" href="#heading-frontend-error-monitoring-sentry">Frontend Error Monitoring (Sentry)</a></li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before jumping in the project, here’s what you’ll need to get the most out of this tutorial:</p>
<h3 id="heading-tools-amp-tech-stack">Tools &amp; Tech Stack</h3>
<p>You’ll be using the following technologies throughout the project:</p>
<ul>
<li><p><strong>Node.js &amp; npm</strong> – Backend runtime and package manager</p>
</li>
<li><p><strong>Express.js</strong> – Web framework for Node</p>
</li>
<li><p><strong>MongoDB Atlas</strong> – Cloud-hosted NoSQL database</p>
</li>
<li><p><strong>Mongoose</strong> – ODM for MongoDB</p>
</li>
<li><p><strong>React</strong> – Frontend UI library</p>
</li>
<li><p><strong>React Router</strong> – For client-side routing</p>
</li>
<li><p><strong>Axios</strong> – For making API requests</p>
</li>
<li><p><strong>Jest &amp; Supertest</strong> – For backend tests</p>
</li>
<li><p><strong>React Testing Library &amp; Cypress</strong> – For Frontend unit and E2E tests</p>
</li>
<li><p><strong>ESLint + Prettier</strong> – For code formatting, linting</p>
</li>
<li><p><strong>Husky</strong> – To setup pre-commit hooks</p>
</li>
<li><p><strong>Helmet, Joi, express-rate-limit, cors</strong> – For security, validation, and best practices</p>
</li>
<li><p><strong>PM2 &amp; NGINX</strong> – For backend deployment</p>
</li>
<li><p><strong>Sentry</strong> – For error monitoring</p>
</li>
</ul>
<h3 id="heading-skills-amp-setup">Skills &amp; Setup</h3>
<ul>
<li><p>Basic knowledge of JavaScript, React, and Node.js</p>
</li>
<li><p>Familiarity with REST APIs and HTTP request/response flows</p>
</li>
<li><p>Git and a GitHub account for version control</p>
</li>
<li><p>A free MongoDB Atlas account</p>
</li>
<li><p>Node.js and npm installed locally (Node 18+ recommended)</p>
</li>
</ul>
<h2 id="heading-project-setup-laying-the-groundwork"><strong>Project Setup: Laying the Groundwork</strong></h2>
<p>A well-structured project is crucial for maintainability. We'll adopt a clear separation between the front end and the back end here.</p>
<h3 id="heading-project-structure"><strong>Project Structure</strong></h3>
<p>This structure clearly separates the React front end (client/) from the Node.js/Express.js back end (server/), promoting modularity and easier management.</p>
<pre><code class="lang-javascript">my-mern-app/                # Root folder
├── client/                 # React frontend
│   ├── public/
│   ├── src/
│   │   ├── components/
│   │   ├── pages/
│   │   ├── App.js
│   │   └── index.js
│   └── package.json
├── server/                 # Node.js/Express.js backend
│   ├── config/
│   ├── controllers/
│   ├── models/
│   ├── routes/
│   ├── services/
│   ├── app.js
│   └── package.json
</code></pre>
<h3 id="heading-code-quality-linting-and-formatting"><strong>Code Quality: Linting and Formatting</strong></h3>
<p>Consistency is key when you’re building a production-grad application like this one. We'll use ESLint with Airbnb style and Prettier for automated code quality and formatting.</p>
<p>To install these tools, run this in your terminal:</p>
<pre><code class="lang-bash">npm install --save-dev eslint prettier eslint-config-airbnb-base eslint-plugin-prettier
</code></pre>
<p>And here are some setups with their recommended configurations:</p>
<p>This configuration sets up ESLint for a Node.js project using the Airbnb and Prettier style guides, with custom rules to relax strict linting constraints like allowing <code>console.log</code> and disabling mandatory function names.</p>
<h4 id="heading-eslintrcjs-server-side-example"><strong>.eslintrc.js (server-side example)</strong></h4>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {

  <span class="hljs-attr">env</span>: {

    <span class="hljs-attr">node</span>: <span class="hljs-literal">true</span>,

    <span class="hljs-attr">commonjs</span>: <span class="hljs-literal">true</span>,

    <span class="hljs-attr">es2021</span>: <span class="hljs-literal">true</span>,

  },

  <span class="hljs-attr">extends</span>: [<span class="hljs-string">"airbnb-base"</span>, <span class="hljs-string">"prettier"</span>],

  <span class="hljs-attr">plugins</span>: [<span class="hljs-string">"prettier"</span>],

  <span class="hljs-attr">parserOptions</span>: {

    <span class="hljs-attr">ecmaVersion</span>: <span class="hljs-number">12</span>,

  },

  <span class="hljs-attr">rules</span>: {

    <span class="hljs-string">"prettier/prettier"</span>: <span class="hljs-string">"error"</span>,

    <span class="hljs-string">"no-console"</span>: <span class="hljs-string">"off"</span>,

    <span class="hljs-string">"func-names"</span>: <span class="hljs-string">"off"</span>,

    <span class="hljs-string">"no-process-exit"</span>: <span class="hljs-string">"off"</span>,

    <span class="hljs-string">"class-methods-use-this"</span>: <span class="hljs-string">"off"</span>,

    <span class="hljs-string">"import/no-extraneous-dependencies"</span>: <span class="hljs-string">"off"</span>,

  },

};
</code></pre>
<h4 id="heading-prettierrc"><strong>.prettierrc</strong></h4>
<p>This config enforces consistent formatting: add semicolons, use trailing commas where valid, and prefer single quotes for strings.</p>
<pre><code class="lang-json">{

  <span class="hljs-attr">"semi"</span>: <span class="hljs-literal">true</span>,

  <span class="hljs-attr">"trailingComma"</span>: <span class="hljs-string">"all"</span>,

  <span class="hljs-attr">"singleQuote"</span>: <span class="hljs-literal">true</span>

}
</code></pre>
<h3 id="heading-version-control-git-essentials"><strong>Version Control: Git Essentials</strong></h3>
<p>Git is indispensable. You can use feature branches and pull requests for collaborative development, making it easier to work on large projects with coworkers. Consider using Husky for pre-commit hooks to enforce linting and testing.</p>
<h4 id="heading-install-husky">Install Husky:</h4>
<p>Install Husky to easily manage Git hooks, allowing you to automate tasks like linting and testing before commits.</p>
<pre><code class="lang-bash">npm install husky --save-dev
</code></pre>
<h4 id="heading-packagejson-add-script">package.json (add script)</h4>
<p>This <code>package.json</code> file sets up a Node.js project named <code>my-mern-app</code>, and configures a <code>prepare</code> script to install Git hooks using Husky (v7). It's ready for adding pre-commit automation, such as linting or testing.</p>
<pre><code class="lang-json">{

  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"my-mern-app"</span>,

  <span class="hljs-attr">"version"</span>: <span class="hljs-string">"1.0.0"</span>,

  <span class="hljs-attr">"description"</span>: <span class="hljs-string">""</span>,

  <span class="hljs-attr">"main"</span>: <span class="hljs-string">"index.js"</span>,

  <span class="hljs-attr">"scripts"</span>: {

    <span class="hljs-attr">"prepare"</span>: <span class="hljs-string">"husky install"</span>

  },

  <span class="hljs-attr">"keywords"</span>: [],

  <span class="hljs-attr">"author"</span>: <span class="hljs-string">""</span>,

  <span class="hljs-attr">"license"</span>: <span class="hljs-string">"ISC"</span>,

  <span class="hljs-attr">"devDependencies"</span>: {

    <span class="hljs-attr">"husky"</span>: <span class="hljs-string">"^7.0.0"</span>

  }

}
</code></pre>
<h4 id="heading-create-a-pre-commit-hook">Create a pre-commit hook</h4>
<p>The below command sets up a pre-commit hook that automatically runs your tests and linter before each commit, ensuring code quality and preventing errors from entering your codebase.</p>
<pre><code class="lang-json">npx husky add .husky/pre-commit <span class="hljs-string">"npm test &amp;&amp; npm run lint"</span>
</code></pre>
<h2 id="heading-testing-ensuring-robustness"><strong>Testing: Ensuring Robustness</strong></h2>
<p>Automated testing is vital. We'll cover unit, integration, and end-to-end testing in this guide.</p>
<h3 id="heading-backend-testing-nodejsexpressjs">Backend Testing (Node.js/Express.js)</h3>
<p>You’ll use Jest for unit testing and Supertest for API integration tests.</p>
<h5 id="heading-install-them-like-this">Install them like this:</h5>
<pre><code class="lang-bash">npm install --save-dev jest supertest
</code></pre>
<p>You’ll use Jest to write unit tests for your JavaScript code and Supertest to test HTTP requests against your Express.js API.</p>
<h4 id="heading-example-test-servertestsauthtestjs">Example Test (server/tests/auth.test.js):</h4>
<p>This test suite uses Supertest to simulate API calls for user registration and login, asserting that the responses have the expected status codes and properties.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> request = <span class="hljs-built_in">require</span>(<span class="hljs-string">'supertest'</span>);

<span class="hljs-keyword">const</span> app = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../app'</span>); <span class="hljs-comment">// Your Express app instance</span>

describe(<span class="hljs-string">'Auth API'</span>, <span class="hljs-function">() =&gt;</span> {

  it(<span class="hljs-string">'should register a new user'</span>, <span class="hljs-keyword">async</span> () =&gt; {

    <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> request(app)

      .post(<span class="hljs-string">'/api/auth/register'</span>)

      .send({

        <span class="hljs-attr">username</span>: <span class="hljs-string">'testuser'</span>,

        <span class="hljs-attr">email</span>: <span class="hljs-string">'test@example.com'</span>,

        <span class="hljs-attr">password</span>: <span class="hljs-string">'password123'</span>,

      });

    expect(res.statusCode).toEqual(<span class="hljs-number">201</span>);

    expect(res.body).toHaveProperty(<span class="hljs-string">'_id'</span>);

  });


  it(<span class="hljs-string">'should login an existing user'</span>, <span class="hljs-keyword">async</span> () =&gt; {

    <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> request(app)

      .post(<span class="hljs-string">'/api/auth/login'</span>)

      .send({

        <span class="hljs-attr">email</span>: <span class="hljs-string">'test@example.com'</span>,

        <span class="hljs-attr">password</span>: <span class="hljs-string">'password123'</span>,

      });

    expect(res.statusCode).toEqual(<span class="hljs-number">200</span>);

    expect(res.headers[<span class="hljs-string">'set-cookie'</span>]).toBeDefined();

  });

});
</code></pre>
<h3 id="heading-frontend-testing-react-testing-library-cypress">Frontend Testing (React Testing Library + Cypress)</h3>
<p>You’ll use Jest and the React Testing Library for unit/integration tests, and Cypress for E2E tests.</p>
<h5 id="heading-you-can-install-these-like-this">You can install these like this:</h5>
<pre><code class="lang-bash">npm install --save-dev @testing-library/react @testing-library/jest-dom jest cypress
</code></pre>
<p>React Testing Library will help you test your React components, and Cypress will provide comprehensive end-to-end testing of your frontend application.</p>
<h4 id="heading-example-component-test-clientsrccomponentsbuttontestjs">Example Component Test (client/src/components/Button.test.js):</h4>
<p>This unit test uses the React Testing Library to render a Button component and verifies that the specified text content is present in the rendered output.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">import</span> { render, screen } <span class="hljs-keyword">from</span> <span class="hljs-string">'@testing-library/react'</span>;

<span class="hljs-keyword">import</span> Button <span class="hljs-keyword">from</span> <span class="hljs-string">'./Button'</span>;


test(<span class="hljs-string">'renders button with text'</span>, <span class="hljs-function">() =&gt;</span> {

  render(<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Button</span>&gt;</span>Click Me<span class="hljs-tag">&lt;/<span class="hljs-name">Button</span>&gt;</span></span>);

  <span class="hljs-keyword">const</span> buttonElement = screen.getByText(<span class="hljs-regexp">/Click Me/i</span>);

  expect(buttonElement).toBeInTheDocument();

});
</code></pre>
<p>The following Cypress test simulates a complete user authentication flow, from registration to login and logout, asserting expected URL changes and page content.</p>
<pre><code class="lang-javascript">Example E2E Test (cypress/e2e/auth.cy.js)

describe(<span class="hljs-string">'Authentication Flow'</span>, <span class="hljs-function">() =&gt;</span> {

  it(<span class="hljs-string">'should allow a user to register and login'</span>, <span class="hljs-function">() =&gt;</span> {

    cy.visit(<span class="hljs-string">'/register'</span>);

    cy.get(<span class="hljs-string">'input[name="username"]'</span>).type(<span class="hljs-string">'e2euser'</span>);

    cy.get(<span class="hljs-string">'input[name="email"]'</span>).type(<span class="hljs-string">'e2e@example.com'</span>);

    cy.get(<span class="hljs-string">'input[name="password"]'</span>).type(<span class="hljs-string">'password123'</span>);

    cy.get(<span class="hljs-string">'button[type="submit"]'</span>).click();

    cy.url().should(<span class="hljs-string">'include'</span>, <span class="hljs-string">'/dashboard'</span>);

    cy.contains(<span class="hljs-string">'Welcome, e2euser'</span>);

    cy.get(<span class="hljs-string">'button'</span>).contains(<span class="hljs-string">'Logout'</span>).click();

    cy.url().should(<span class="hljs-string">'include'</span>, <span class="hljs-string">'/login'</span>);

    cy.get(<span class="hljs-string">'input[name="email"]'</span>).type(<span class="hljs-string">'e2e@example.com'</span>);

    cy.get(<span class="hljs-string">'input[name="password"]'</span>).type(<span class="hljs-string">'password123'</span>);

    cy.get(<span class="hljs-string">'button[type="submit"]'</span>).click();

    cy.url().should(<span class="hljs-string">'include'</span>, <span class="hljs-string">'/dashboard'</span>);

  });

});
</code></pre>
<h2 id="heading-how-to-build-the-task-manager"><strong>How to Build the Task Manager</strong></h2>
<p>We'll build a simple Task Manager with user authentication and CRUD operations for tasks so you can see how the whole thing comes together.</p>
<h3 id="heading-backend-implementation-nodejsexpressjs">Backend Implementation (Node.js/Express.js)</h3>
<h4 id="heading-dependencies">Dependencies</h4>
<p>Start by installing our core backend libraries: Express for routing, Mongoose for MongoDB interactions, dotenv for environment variables, bcrypt/jsonwebtoken/cookie-parser for secure authentication, and helmet for setting secure HTTP headers:</p>
<pre><code class="lang-bash">npm install express mongoose dotenv bcryptjs jsonwebtoken cookie-parser
</code></pre>
<h4 id="heading-serverappjs-entry-point">server/app.js (Entry Point)</h4>
<p>Next, we’ll set up the first or the main entry point for the backend. This is the main Express.js application file, which configures middleware, establishes a MongoDB connection, and sets up API routes for authentication and task management.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);

<span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mongoose'</span>);

<span class="hljs-keyword">const</span> dotenv = <span class="hljs-built_in">require</span>(<span class="hljs-string">'dotenv'</span>);

<span class="hljs-keyword">const</span> cookieParser = <span class="hljs-built_in">require</span>(<span class="hljs-string">'cookie-parser'</span>);

<span class="hljs-keyword">const</span> helmet = <span class="hljs-built_in">require</span>(<span class="hljs-string">'helmet'</span>);

<span class="hljs-keyword">const</span> authRoutes = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./routes/authRoutes'</span>);

<span class="hljs-keyword">const</span> taskRoutes = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./routes/taskRoutes'</span>);

<span class="hljs-keyword">const</span> { notFound, errorHandler } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./middleware/errorMiddleware'</span>);

dotenv.config();


<span class="hljs-keyword">const</span> app = express();

app.use(helmet());

app.use(express.json());

app.use(cookieParser());


mongoose.connect(process.env.MONGO_URI)

  .then(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'MongoDB connected!'</span>))

  .catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'MongoDB connection error:'</span>, err));


app.use(<span class="hljs-string">'/api/auth'</span>, authRoutes);

app.use(<span class="hljs-string">'/api/tasks'</span>, taskRoutes);


app.get(<span class="hljs-string">'/'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {

  res.send(<span class="hljs-string">'MERN Task Manager API is running!'</span>);

});


app.use(notFound);

app.use(errorHandler);


<span class="hljs-keyword">const</span> PORT = process.env.PORT || <span class="hljs-number">5000</span>;

app.listen(PORT, <span class="hljs-function">() =&gt;</span> {

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server running on port <span class="hljs-subst">${PORT}</span>`</span>);

});
</code></pre>
<h4 id="heading-serverenv">server/.env</h4>
<p>To avoid hardcoding secrets, we’ll add a <code>.env</code> file where we can securely store environment variables, such as our database URI and JWT secret. This file stores sensitive environment variables such as your MongoDB connection string, server port, and JWT secret, keeping them secure and separate from your codebase.</p>
<pre><code class="lang-bash">MONGO_URI=your_mongodb_connection_string_here

PORT=5000

JWT_SECRET=supersecretjwtkey
</code></pre>
<h4 id="heading-servermodelsuserjs">server/models/User.js</h4>
<p>Now, let’s define our User model using MongoDB. This schema includes fields for username, email, and password, with pre-save hooks for password hashing and a method for password comparison.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mongoose'</span>);

<span class="hljs-keyword">const</span> bcrypt = <span class="hljs-built_in">require</span>(<span class="hljs-string">'bcryptjs'</span>);


<span class="hljs-keyword">const</span> UserSchema = <span class="hljs-keyword">new</span> mongoose.Schema({

  <span class="hljs-attr">username</span>: {

    <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,

    <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,

    <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>,

  },

  <span class="hljs-attr">email</span>: {

    <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,

    <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,

    <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>,

  },

  <span class="hljs-attr">password</span>: {

    <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,

    <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,

  },

});

UserSchema.pre(<span class="hljs-string">'save'</span>, <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">next</span>) </span>{

  <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isModified(<span class="hljs-string">'password'</span>)) {

    next();

  }

  <span class="hljs-keyword">const</span> salt = <span class="hljs-keyword">await</span> bcrypt.genSalt(<span class="hljs-number">10</span>);

  <span class="hljs-built_in">this</span>.password = <span class="hljs-keyword">await</span> bcrypt.hash(<span class="hljs-built_in">this</span>.password, salt);

});


UserSchema.methods.matchPassword = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">enteredPassword</span>) </span>{

  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> bcrypt.compare(enteredPassword, <span class="hljs-built_in">this</span>.password);

};


<span class="hljs-built_in">module</span>.exports = mongoose.model(<span class="hljs-string">'User'</span>, UserSchema);
</code></pre>
<h4 id="heading-servermodelstaskjs">server/models/Task.js</h4>
<p>Next, we’ll create the Task model. This schema defines the Task model, which links each task to a user and includes fields for title, description, completion status, and creation timestamp.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mongoose'</span>);


<span class="hljs-keyword">const</span> TaskSchema = <span class="hljs-keyword">new</span> mongoose.Schema({

  <span class="hljs-attr">user</span>: {

    <span class="hljs-attr">type</span>: mongoose.Schema.Types.ObjectId,

    <span class="hljs-attr">ref</span>: <span class="hljs-string">'User'</span>,

    <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,

  },

  <span class="hljs-attr">title</span>: {

    <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,

    <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,

    <span class="hljs-attr">trim</span>: <span class="hljs-literal">true</span>,

  },

  <span class="hljs-attr">description</span>: {

    <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,

    <span class="hljs-attr">trim</span>: <span class="hljs-literal">true</span>,

  },

  <span class="hljs-attr">completed</span>: {

    <span class="hljs-attr">type</span>: <span class="hljs-built_in">Boolean</span>,

    <span class="hljs-attr">default</span>: <span class="hljs-literal">false</span>,

  },

  <span class="hljs-attr">createdAt</span>: {

    <span class="hljs-attr">type</span>: <span class="hljs-built_in">Date</span>,

    <span class="hljs-attr">default</span>: <span class="hljs-built_in">Date</span>.now,

  },

});


<span class="hljs-built_in">module</span>.exports = mongoose.model(<span class="hljs-string">'Task'</span>, TaskSchema);
</code></pre>
<h4 id="heading-servercontrollersauthcontrollerjs">server/controllers/authController.js</h4>
<p>Let’s build out the authentication controller. This controller handles user authentication flows, including registration, login, logout, and fetching user profiles, using JWTs and secure HTTP-only cookies.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../models/User'</span>);

<span class="hljs-keyword">const</span> jwt = <span class="hljs-built_in">require</span>(<span class="hljs-string">'jsonwebtoken'</span>);

<span class="hljs-keyword">const</span> generateToken = <span class="hljs-function">(<span class="hljs-params">id</span>) =&gt;</span> {

  <span class="hljs-keyword">return</span> jwt.sign({ id }, process.env.JWT_SECRET, {

    <span class="hljs-attr">expiresIn</span>: <span class="hljs-string">'1h'</span>,

  });

};

<span class="hljs-built_in">exports</span>.registerUser = <span class="hljs-keyword">async</span> (req, res) =&gt; {

  <span class="hljs-keyword">const</span> { username, email, password } = req.body;

  <span class="hljs-keyword">try</span> {

    <span class="hljs-keyword">const</span> userExists = <span class="hljs-keyword">await</span> User.findOne({ email });

    <span class="hljs-keyword">if</span> (userExists) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'User already exists'</span> });

    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.create({ username, email, password });

    <span class="hljs-keyword">if</span> (user) {

      <span class="hljs-keyword">const</span> token = generateToken(user._id);

      res.cookie(<span class="hljs-string">'token'</span>, token, { <span class="hljs-attr">httpOnly</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">secure</span>: process.env.NODE_ENV === <span class="hljs-string">'production'</span>, <span class="hljs-attr">maxAge</span>: <span class="hljs-number">3600000</span> });

      res.status(<span class="hljs-number">201</span>).json({ <span class="hljs-attr">id</span>: user.id, <span class="hljs-attr">username</span>: user.username, <span class="hljs-attr">email</span>: user.email });

    } <span class="hljs-keyword">else</span> {

      res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Invalid user data'</span> });

    }

  } <span class="hljs-keyword">catch</span> (error) {

    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">message</span>: error.message });

  }

};


<span class="hljs-built_in">exports</span>.loginUser = <span class="hljs-keyword">async</span> (req, res) =&gt; {

  <span class="hljs-keyword">const</span> { email, password } = req.body;

  <span class="hljs-keyword">try</span> {

    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findOne({ email });

    <span class="hljs-keyword">if</span> (user &amp;&amp; (<span class="hljs-keyword">await</span> user.matchPassword(password))) {

      <span class="hljs-keyword">const</span> token = generateToken(user._id);

      res.cookie(<span class="hljs-string">'token'</span>, token, { <span class="hljs-attr">httpOnly</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">secure</span>: process.env.NODE_ENV === <span class="hljs-string">'production'</span>, <span class="hljs-attr">maxAge</span>: <span class="hljs-number">3600000</span> });

      res.json({ <span class="hljs-attr">id</span>: user.id, <span class="hljs-attr">username</span>: user.username, <span class="hljs-attr">email</span>: user.email });

    } <span class="hljs-keyword">else</span> {

      res.status(<span class="hljs-number">401</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Invalid email or password'</span> });

    }

  } <span class="hljs-keyword">catch</span> (error) {

    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">message</span>: error.message });

  }

};


<span class="hljs-built_in">exports</span>.logoutUser = <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {

  res.cookie(<span class="hljs-string">'token'</span>, <span class="hljs-string">''</span>, { <span class="hljs-attr">httpOnly</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">expires</span>: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(<span class="hljs-number">0</span>) });

  res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Logged out successfully'</span> });

};


<span class="hljs-built_in">exports</span>.getUserProfile = <span class="hljs-keyword">async</span> (req, res) =&gt; {

  <span class="hljs-keyword">try</span> {

    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findById(req.user._id).select(<span class="hljs-string">'-password'</span>);

    <span class="hljs-keyword">if</span> (user) {

      res.json(user);

    } <span class="hljs-keyword">else</span> {

      res.status(<span class="hljs-number">404</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'User not found'</span> });

    }

  } <span class="hljs-keyword">catch</span> (error) {

    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">message</span>: error.message });

  }

};
</code></pre>
<h4 id="heading-servercontrollerstaskcontrollerjs">server/controllers/taskController.js</h4>
<p>Now it’s time to implement the task controller. This controller provides the logic for fetching, creating, updating, and deleting tasks, ensuring that users can only interact with their tasks.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> Task = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../models/Task'</span>);


<span class="hljs-built_in">exports</span>.getTasks = <span class="hljs-keyword">async</span> (req, res) =&gt; {

  <span class="hljs-keyword">try</span> {

    <span class="hljs-keyword">const</span> tasks = <span class="hljs-keyword">await</span> Task.find({ <span class="hljs-attr">user</span>: req.user._id });

    res.status(<span class="hljs-number">200</span>).json(tasks);

  } <span class="hljs-keyword">catch</span> (error) {

    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">message</span>: error.message });

  }

};


<span class="hljs-built_in">exports</span>.createTask = <span class="hljs-keyword">async</span> (req, res) =&gt; {

  <span class="hljs-keyword">const</span> { title, description } = req.body;

  <span class="hljs-keyword">if</span> (!title) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Please add a title'</span> });

  <span class="hljs-keyword">try</span> {

    <span class="hljs-keyword">const</span> task = <span class="hljs-keyword">await</span> Task.create({ title, description, <span class="hljs-attr">user</span>: req.user._id });

    res.status(<span class="hljs-number">201</span>).json(task);

  } <span class="hljs-keyword">catch</span> (error) {

    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">message</span>: error.message });

  }

};


<span class="hljs-built_in">exports</span>.updateTask = <span class="hljs-keyword">async</span> (req, res) =&gt; {

  <span class="hljs-keyword">try</span> {

    <span class="hljs-keyword">const</span> task = <span class="hljs-keyword">await</span> Task.findById(req.params.id);

    <span class="hljs-keyword">if</span> (!task) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">404</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Task not found'</span> });

    <span class="hljs-keyword">if</span> (task.user.toString() !== req.user._id.toString()) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">401</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Not authorized'</span> });


    <span class="hljs-keyword">const</span> updatedTask = <span class="hljs-keyword">await</span> Task.findByIdAndUpdate(req.params.id, req.body, { <span class="hljs-attr">new</span>: <span class="hljs-literal">true</span>, <span class="hljs-attr">runValidators</span>: <span class="hljs-literal">true</span> });

    res.status(<span class="hljs-number">200</span>).json(updatedTask);

  } <span class="hljs-keyword">catch</span> (error) {

    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">message</span>: error.message });

  }

};


<span class="hljs-built_in">exports</span>.deleteTask = <span class="hljs-keyword">async</span> (req, res) =&gt; {

  <span class="hljs-keyword">try</span> {

    <span class="hljs-keyword">const</span> task = <span class="hljs-keyword">await</span> Task.findById(req.params.id);

    <span class="hljs-keyword">if</span> (!task) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">404</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Task not found'</span> });

    <span class="hljs-keyword">if</span> (task.user.toString() !== req.user._id.toString()) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">401</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Not authorized'</span> });


    <span class="hljs-keyword">await</span> Task.deleteOne({ <span class="hljs-attr">_id</span>: req.params.id });

    res.status(<span class="hljs-number">200</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Task removed'</span> });

  } <span class="hljs-keyword">catch</span> (error) {

    res.status(<span class="hljs-number">500</span>).json({ <span class="hljs-attr">message</span>: error.message });

  }

};
</code></pre>
<h4 id="heading-servermiddlewareauthmiddlewarejs">server/middleware/authMiddleware.js</h4>
<p>To protect private routes<strong>,</strong> we will create a middleware that verifies the JWT from the request's cookies, ensuring that only authenticated users can access specific endpoints.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> jwt = <span class="hljs-built_in">require</span>(<span class="hljs-string">'jsonwebtoken'</span>);

<span class="hljs-keyword">const</span> User = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../models/User'</span>);

<span class="hljs-built_in">exports</span>.protect = <span class="hljs-keyword">async</span> (req, res, next) =&gt; {

  <span class="hljs-keyword">let</span> token;

  <span class="hljs-keyword">if</span> (req.cookies.token) {

    <span class="hljs-keyword">try</span> {

      token = req.cookies.token;

      <span class="hljs-keyword">const</span> decoded = jwt.verify(token, process.env.JWT_SECRET);

      req.user = <span class="hljs-keyword">await</span> User.findById(decoded.id).select(<span class="hljs-string">'-password'</span>);

      next();

    } <span class="hljs-keyword">catch</span> (error) {

      res.status(<span class="hljs-number">401</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Not authorized, token failed'</span> });

    }

  } <span class="hljs-keyword">else</span> {

    res.status(<span class="hljs-number">401</span>).json({ <span class="hljs-attr">message</span>: <span class="hljs-string">'Not authorized, no token'</span> });

  }

};
</code></pre>
<h4 id="heading-servermiddlewareerrormiddlewarejs">server/middleware/errorMiddleware.js</h4>
<p>To handle errors cleanly across our backend, we’ll add global error-handling middleware that can handle 404 Not Found errors and provide a centralized error-handling mechanism for consistent API error responses.</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">exports</span>.notFound = <span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {

  <span class="hljs-keyword">const</span> error = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`Not Found - <span class="hljs-subst">${req.originalUrl}</span>`</span>);

  res.status(<span class="hljs-number">404</span>);

  next(error);

};


<span class="hljs-built_in">exports</span>.errorHandler = <span class="hljs-function">(<span class="hljs-params">err, req, res, next</span>) =&gt;</span> {

  <span class="hljs-keyword">const</span> statusCode = res.statusCode === <span class="hljs-number">200</span> ? <span class="hljs-number">500</span> : res.statusCode;

  res.status(statusCode);

  res.json({

    <span class="hljs-attr">message</span>: err.message,

    <span class="hljs-attr">stack</span>: process.env.NODE_ENV === <span class="hljs-string">'production'</span> ? <span class="hljs-literal">null</span> : err.stack,

  });

};
</code></pre>
<h4 id="heading-serverroutesauthroutesjs">server/routes/authRoutes.js</h4>
<p>Next, let’s define our authentication routes. These endpoints enable user authentication and map HTTP methods to their corresponding controller functions.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);

<span class="hljs-keyword">const</span> { registerUser, loginUser, logoutUser, getUserProfile } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../controllers/authController'</span>);

<span class="hljs-keyword">const</span> { protect } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../middleware/authMiddleware'</span>);


<span class="hljs-keyword">const</span> router = express.Router();


router.post(<span class="hljs-string">'/register'</span>, registerUser);

router.post(<span class="hljs-string">'/login'</span>, loginUser);

router.get(<span class="hljs-string">'/logout'</span>, logoutUser);

router.get(<span class="hljs-string">'/profile'</span>, protect, getUserProfile);


<span class="hljs-built_in">module</span>.exports = router;
</code></pre>
<h4 id="heading-serverroutestaskroutesjs">server/routes/taskRoutes.js</h4>
<p>Now we’ll add the routes for task operations. This file defines the API routes for task management, applying the protect middleware to secure all task-related operations.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);

<span class="hljs-keyword">const</span> { getTasks, createTask, updateTask, deleteTask } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../controllers/taskController'</span>);

<span class="hljs-keyword">const</span> { protect } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../middleware/authMiddleware'</span>);

<span class="hljs-keyword">const</span> router = express.Router();

router.route(<span class="hljs-string">'/'</span>).get(protect, getTasks).post(protect, createTask);

router.route(<span class="hljs-string">'/:id'</span>).put(protect, updateTask).delete(protect, deleteTask);

<span class="hljs-built_in">module</span>.exports = router;
</code></pre>
<h3 id="heading-frontend-implementation-react">Frontend Implementation (React)</h3>
<h4 id="heading-dependencies-1">Dependencies</h4>
<p>Now, you’ll need to initialize a new React project and install your essential libraries: Axios for HTTP requests, React Router for navigation, and React Toastify for displaying notifications.</p>
<pre><code class="lang-bash">npm install axios react-router-dom react-toastify
</code></pre>
<h4 id="heading-clientsrcindexjs">client/src/index.js</h4>
<p>Let’s start the frontend by setting up the entry point. Here we are rendering the main App component and wrapping it with AuthProvider to provide authentication context globally.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">import</span> ReactDOM <span class="hljs-keyword">from</span> <span class="hljs-string">'react-dom/client'</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">'./index.css'</span>;

<span class="hljs-keyword">import</span> App <span class="hljs-keyword">from</span> <span class="hljs-string">'./App'</span>;

<span class="hljs-keyword">import</span> { AuthProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">'./context/AuthContext'</span>;


<span class="hljs-keyword">const</span> root = ReactDOM.createRoot(<span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'root'</span>));

root.render(

  <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">React.StrictMode</span>&gt;</span>

    <span class="hljs-tag">&lt;<span class="hljs-name">AuthProvider</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">App</span> /&gt;</span>

    <span class="hljs-tag">&lt;/<span class="hljs-name">AuthProvider</span>&gt;</span>

  <span class="hljs-tag">&lt;/<span class="hljs-name">React.StrictMode</span>&gt;</span></span>

);
</code></pre>
<h4 id="heading-clientsrcappjs">client/src/App.js</h4>
<p>Next, we’ll define our main App component. This sets up the client-side routing for the application, and defines public and private routes, and includes a navigation bar and toast notification system.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">import</span> { BrowserRouter <span class="hljs-keyword">as</span> Router, Routes, Route } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-keyword">import</span> { ToastContainer } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-toastify'</span>;

<span class="hljs-keyword">import</span> <span class="hljs-string">'react-toastify/dist/ReactToastify.css'</span>;


<span class="hljs-keyword">import</span> Navbar <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/Navbar'</span>;

<span class="hljs-keyword">import</span> Register <span class="hljs-keyword">from</span> <span class="hljs-string">'./pages/Register'</span>;

<span class="hljs-keyword">import</span> Login <span class="hljs-keyword">from</span> <span class="hljs-string">'./pages/Login'</span>;

<span class="hljs-keyword">import</span> Dashboard <span class="hljs-keyword">from</span> <span class="hljs-string">'./pages/Dashboard'</span>;

<span class="hljs-keyword">import</span> PrivateRoute <span class="hljs-keyword">from</span> <span class="hljs-string">'./components/PrivateRoute'</span>;


<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{

  <span class="hljs-keyword">return</span> (

    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Router</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">Navbar</span> /&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">ToastContainer</span> /&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"container"</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">Routes</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/register"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Register</span> /&gt;</span>} /&gt;

          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/login"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Login</span> /&gt;</span>} /&gt;

          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/dashboard"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">PrivateRoute</span> /&gt;</span>}&gt;

            <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">index</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">Dashboard</span> /&gt;</span>} /&gt;

          <span class="hljs-tag">&lt;/<span class="hljs-name">Route</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">Route</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"/"</span> <span class="hljs-attr">element</span>=<span class="hljs-string">{</span>&lt;<span class="hljs-attr">h1</span>&gt;</span>Welcome to Task Manager!<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>} /&gt;

        <span class="hljs-tag">&lt;/<span class="hljs-name">Routes</span>&gt;</span>

      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-tag">&lt;/<span class="hljs-name">Router</span>&gt;</span></span>

  );

}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<h4 id="heading-clientsrccontextauthcontextjs">client/src/context/AuthContext.js</h4>
<p>We’ll create an authentication context that manages the global authentication state. It provides functions for user login, registration, and logout, and automatically loads user data on component mount.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { createContext, useState, useEffect } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;

<span class="hljs-keyword">const</span> AuthContext = createContext();

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> AuthProvider = <span class="hljs-function">(<span class="hljs-params">{ children }</span>) =&gt;</span> {

  <span class="hljs-keyword">const</span> [user, setUser] = useState(<span class="hljs-literal">null</span>);

  <span class="hljs-keyword">const</span> [loading, setLoading] = useState(<span class="hljs-literal">true</span>);


  useEffect(<span class="hljs-function">() =&gt;</span> {

    <span class="hljs-keyword">const</span> loadUser = <span class="hljs-keyword">async</span> () =&gt; {

      <span class="hljs-keyword">try</span> {

        <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">'/api/auth/profile'</span>);

        setUser(res.data);

      } <span class="hljs-keyword">catch</span> (err) {

        setUser(<span class="hljs-literal">null</span>);

      } <span class="hljs-keyword">finally</span> {

        setLoading(<span class="hljs-literal">false</span>);

      }

    };

    loadUser();

  }, []);


  <span class="hljs-keyword">const</span> login = <span class="hljs-keyword">async</span> (email, password) =&gt; {

    <span class="hljs-keyword">try</span> {

      <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> axios.post(<span class="hljs-string">'/api/auth/login'</span>, { email, password });

      setUser(res.data);

      <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;

    } <span class="hljs-keyword">catch</span> (err) {

      <span class="hljs-built_in">console</span>.error(err.response.data.message);

      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;

    }

  };


  <span class="hljs-keyword">const</span> register = <span class="hljs-keyword">async</span> (username, email, password) =&gt; {

    <span class="hljs-keyword">try</span> {

      <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> axios.post(<span class="hljs-string">'/api/auth/register'</span>, { username, email, password });

      setUser(res.data);

      <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;

    } <span class="hljs-keyword">catch</span> (err) {

      <span class="hljs-built_in">console</span>.error(err.response.data.message);

      <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;

    }

  };


  <span class="hljs-keyword">const</span> logout = <span class="hljs-keyword">async</span> () =&gt; {

    <span class="hljs-keyword">try</span> {

      <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">'/api/auth/logout'</span>);

      setUser(<span class="hljs-literal">null</span>);

    } <span class="hljs-keyword">catch</span> (err) {

      <span class="hljs-built_in">console</span>.error(err);

    }

  };


  <span class="hljs-keyword">return</span> (

    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">AuthContext.Provider</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">user</span>, <span class="hljs-attr">loading</span>, <span class="hljs-attr">login</span>, <span class="hljs-attr">register</span>, <span class="hljs-attr">logout</span> }}&gt;</span>

      {children}

    <span class="hljs-tag">&lt;/<span class="hljs-name">AuthContext.Provider</span>&gt;</span></span>

  );

};


<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> AuthContext;
</code></pre>
<h4 id="heading-clientsrccomponentsnavbarjs">client/src/components/Navbar.js</h4>
<p>Here’s a dynamic navigation bar component that dynamically displays links based on the user's authentication status, showing either login/register options or a welcome message and logout button.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useContext } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">import</span> { Link } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-keyword">import</span> AuthContext <span class="hljs-keyword">from</span> <span class="hljs-string">'../context/AuthContext'</span>;


<span class="hljs-keyword">const</span> Navbar = <span class="hljs-function">() =&gt;</span> {

  <span class="hljs-keyword">const</span> { user, logout } = useContext(AuthContext);


  <span class="hljs-keyword">return</span> (

    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">nav</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Task Manager<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>

        {user ? (

          <span class="hljs-tag">&lt;&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>Welcome, {user.username}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{logout}</span>&gt;</span>Logout<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/dashboard"</span>&gt;</span>Dashboard<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>

          <span class="hljs-tag">&lt;/&gt;</span>

        ) : (

          <span class="hljs-tag">&lt;&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/login"</span>&gt;</span>Login<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">Link</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/register"</span>&gt;</span>Register<span class="hljs-tag">&lt;/<span class="hljs-name">Link</span>&gt;</span>

          <span class="hljs-tag">&lt;/&gt;</span></span>

        )}

      &lt;/div&gt;

    &lt;/nav&gt;

  );

};


<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Navbar;
</code></pre>
<h4 id="heading-clientsrccomponentsprivateroutejs">client/src/components/PrivateRoute.js</h4>
<p>To protect certain pages, we can create a Private Route component. This will be a guard for private routes, ensuring that only authenticated users can access them and redirecting unauthenticated users to the login page.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useContext } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">import</span> { Navigate, Outlet } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-keyword">import</span> AuthContext <span class="hljs-keyword">from</span> <span class="hljs-string">'../context/AuthContext'</span>;


<span class="hljs-keyword">const</span> PrivateRoute = <span class="hljs-function">() =&gt;</span> {

  <span class="hljs-keyword">const</span> { user, loading } = useContext(AuthContext);


  <span class="hljs-keyword">if</span> (loading) {

    <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>Loading...<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>; <span class="hljs-comment">// Or a spinner</span>

  }


  <span class="hljs-keyword">return</span> user ? <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Outlet</span> /&gt;</span></span> : <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Navigate</span> <span class="hljs-attr">to</span>=<span class="hljs-string">"/login"</span> <span class="hljs-attr">replace</span> /&gt;</span></span>;

};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> PrivateRoute;
</code></pre>
<h4 id="heading-clientsrcpagesregisterjs">client/src/pages/Register.js</h4>
<p>Now, let’s create the Register component, which provides a user registration form, handles input state and form submission, and displays success or error messages using toast notifications.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useContext } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">import</span> { useNavigate } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-keyword">import</span> { toast } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-toastify'</span>;

<span class="hljs-keyword">import</span> AuthContext <span class="hljs-keyword">from</span> <span class="hljs-string">'../context/AuthContext'</span>;


<span class="hljs-keyword">const</span> Register = <span class="hljs-function">() =&gt;</span> {

  <span class="hljs-keyword">const</span> [username, setUsername] = useState(<span class="hljs-string">''</span>);

  <span class="hljs-keyword">const</span> [email, setEmail] = useState(<span class="hljs-string">''</span>);

  <span class="hljs-keyword">const</span> [password, setPassword] = useState(<span class="hljs-string">''</span>);

  <span class="hljs-keyword">const</span> { register } = useContext(AuthContext);

  <span class="hljs-keyword">const</span> navigate = useNavigate();


  <span class="hljs-keyword">const</span> handleSubmit = <span class="hljs-keyword">async</span> (e) =&gt; {

    e.preventDefault();

    <span class="hljs-keyword">const</span> success = <span class="hljs-keyword">await</span> register(username, email, password);

    <span class="hljs-keyword">if</span> (success) {

      toast.success(<span class="hljs-string">'Registration successful!'</span>);

      navigate(<span class="hljs-string">'/dashboard'</span>);

    } <span class="hljs-keyword">else</span> {

      toast.error(<span class="hljs-string">'Registration failed. Please try again.'</span>);

    }

  };


  <span class="hljs-keyword">return</span> (

    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Register<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Username:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{username}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setUsername(e.target.value)} required /&gt;

        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Email:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{email}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setEmail(e.target.value)} required /&gt;

        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Password:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{password}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setPassword(e.target.value)} required /&gt;

        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Register<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>

    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

  );

};


<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Register;
</code></pre>
<h4 id="heading-clientsrcpagesloginjs">client/src/pages/Login.js</h4>
<p>Now, for the login form, it works similarly to the register page but logs users into the system instead. This page manages input fields, handles form submissions, and provides feedback via toast notifications.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useContext } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">import</span> { useNavigate } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-router-dom'</span>;

<span class="hljs-keyword">import</span> { toast } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-toastify'</span>;

<span class="hljs-keyword">import</span> AuthContext <span class="hljs-keyword">from</span> <span class="hljs-string">'../context/AuthContext'</span>;


<span class="hljs-keyword">const</span> Login = <span class="hljs-function">() =&gt;</span> {

  <span class="hljs-keyword">const</span> [email, setEmail] = useState(<span class="hljs-string">''</span>);

  <span class="hljs-keyword">const</span> [password, setPassword] = useState(<span class="hljs-string">''</span>);

  <span class="hljs-keyword">const</span> { login } = useContext(AuthContext);

  <span class="hljs-keyword">const</span> navigate = useNavigate();


  <span class="hljs-keyword">const</span> handleSubmit = <span class="hljs-keyword">async</span> (e) =&gt; {

    e.preventDefault();

    <span class="hljs-keyword">const</span> success = <span class="hljs-keyword">await</span> login(email, password);

    <span class="hljs-keyword">if</span> (success) {

      toast.success(<span class="hljs-string">'Login successful!'</span>);

      navigate(<span class="hljs-string">'/dashboard'</span>);

    } <span class="hljs-keyword">else</span> {

      toast.error(<span class="hljs-string">'Login failed. Invalid credentials.'</span>);

    }

  };


  <span class="hljs-keyword">return</span> (

    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Login<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleSubmit}</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Email:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{email}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setEmail(e.target.value)} required /&gt;

        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">label</span>&gt;</span>Password:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>

          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"password"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">{password}</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setPassword(e.target.value)} required /&gt;

        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Login<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>

    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

  );

};


<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Login;
</code></pre>
<h4 id="heading-clientsrcpagesdashboardjs">client/src/pages/Dashboard.js</h4>
<p>Finally, we’ll build the Dashboard page. This dashboard component displays a user's tasks, allowing them to create new tasks, mark tasks as complete or incomplete, and delete tasks, with real-time updates.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState, useEffect, useContext } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">import</span> axios <span class="hljs-keyword">from</span> <span class="hljs-string">'axios'</span>;

<span class="hljs-keyword">import</span> { toast } <span class="hljs-keyword">from</span> <span class="hljs-string">'react-toastify'</span>;

<span class="hljs-keyword">import</span> AuthContext <span class="hljs-keyword">from</span> <span class="hljs-string">'../context/AuthContext'</span>;


<span class="hljs-keyword">const</span> Dashboard = <span class="hljs-function">() =&gt;</span> {

  <span class="hljs-keyword">const</span> { user } = useContext(AuthContext);

  <span class="hljs-keyword">const</span> [tasks, setTasks] = useState([]);

  <span class="hljs-keyword">const</span> [newTaskTitle, setNewTaskTitle] = useState(<span class="hljs-string">''</span>);

  <span class="hljs-keyword">const</span> [newTaskDescription, setNewTaskDescription] = useState(<span class="hljs-string">''</span>);


  useEffect(<span class="hljs-function">() =&gt;</span> {

    <span class="hljs-keyword">if</span> (user) {

      fetchTasks();

    }

  }, [user]);


  <span class="hljs-keyword">const</span> fetchTasks = <span class="hljs-keyword">async</span> () =&gt; {

    <span class="hljs-keyword">try</span> {

      <span class="hljs-keyword">const</span> res = <span class="hljs-keyword">await</span> axios.get(<span class="hljs-string">'/api/tasks'</span>);

      setTasks(res.data);

    } <span class="hljs-keyword">catch</span> (err) {

      toast.error(<span class="hljs-string">'Failed to fetch tasks.'</span>);

      <span class="hljs-built_in">console</span>.error(err);

    }

  };


  <span class="hljs-keyword">const</span> handleCreateTask = <span class="hljs-keyword">async</span> (e) =&gt; {

    e.preventDefault();

    <span class="hljs-keyword">try</span> {

      <span class="hljs-keyword">await</span> axios.post(<span class="hljs-string">'/api/tasks'</span>, { <span class="hljs-attr">title</span>: newTaskTitle, <span class="hljs-attr">description</span>: newTaskDescription });

      setNewTaskTitle(<span class="hljs-string">''</span>);

      setNewTaskDescription(<span class="hljs-string">''</span>);

      toast.success(<span class="hljs-string">'Task created successfully!'</span>);

      fetchTasks();

    } <span class="hljs-keyword">catch</span> (err) {

      toast.error(<span class="hljs-string">'Failed to create task.'</span>);

      <span class="hljs-built_in">console</span>.error(err);

    }

  };


  <span class="hljs-keyword">const</span> handleUpdateTask = <span class="hljs-keyword">async</span> (id, completed) =&gt; {

    <span class="hljs-keyword">try</span> {

      <span class="hljs-keyword">await</span> axios.put(<span class="hljs-string">`/api/tasks/<span class="hljs-subst">${id}</span>`</span>, { completed });

      toast.success(<span class="hljs-string">'Task updated successfully!'</span>);

      fetchTasks();

    } <span class="hljs-keyword">catch</span> (err) {

      toast.error(<span class="hljs-string">'Failed to update task.'</span>);

      <span class="hljs-built_in">console</span>.error(err);

    }

  };


  <span class="hljs-keyword">const</span> handleDeleteTask = <span class="hljs-keyword">async</span> (id) =&gt; {

    <span class="hljs-keyword">try</span> {

      <span class="hljs-keyword">await</span> axios.delete(<span class="hljs-string">`/api/tasks/<span class="hljs-subst">${id}</span>`</span>);

      toast.success(<span class="hljs-string">'Task deleted successfully!'</span>);

      fetchTasks();

    } <span class="hljs-keyword">catch</span> (err) {

      toast.error(<span class="hljs-string">'Failed to delete task.'</span>);

      <span class="hljs-built_in">console</span>.error(err);

    }

  };


  <span class="hljs-keyword">return</span> (

    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Welcome, {user ? user.username : 'Guest'}!<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Your Tasks<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">form</span> <span class="hljs-attr">onSubmit</span>=<span class="hljs-string">{handleCreateTask}</span>&gt;</span>

        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>

          <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>

          <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"New Task Title"</span>

          <span class="hljs-attr">value</span>=<span class="hljs-string">{newTaskTitle}</span>

          <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setNewTaskTitle(e.target.value)}

          required

        /&gt;

        <span class="hljs-tag">&lt;<span class="hljs-name">input</span>

          <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span>

          <span class="hljs-attr">placeholder</span>=<span class="hljs-string">"Description (optional)"</span>

          <span class="hljs-attr">value</span>=<span class="hljs-string">{newTaskDescription}</span>

          <span class="hljs-attr">onChange</span>=<span class="hljs-string">{(e)</span> =&gt;</span> setNewTaskDescription(e.target.value)}

        /&gt;

        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Add Task<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

      <span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>

      <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>

        {tasks.map((task) =&gt; (

          <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">key</span>=<span class="hljs-string">{task._id}</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">textDecoration:</span> <span class="hljs-attr">task.completed</span> ? '<span class="hljs-attr">line-through</span>' <span class="hljs-attr">:</span> '<span class="hljs-attr">none</span>' }}&gt;</span>

              {task.title}: {task.description}

            <span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> handleUpdateTask(task._id, !task.completed)}&gt;

              {task.completed ? 'Mark Incomplete' : 'Mark Complete'}

            <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

            <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> handleDeleteTask(task._id)}&gt;Delete<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>

          <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>

        ))}

      <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>

    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>

  );

};


<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Dashboard;
</code></pre>
<h2 id="heading-deployment-from-localhost-to-live"><strong>Deployment: From Localhost to Live</strong></h2>
<p>Deploying a MERN stack application involves deploying the backend API and the frontend React application separately.</p>
<p>Let’s talk about why we do it separately. As you have seen from above, in a MERN stack app, the frontend and backend are separate by design. React handles the UI, while Express and Node handle server logic and API calls. Because they serve different roles, you'll need to deploy them separately.</p>
<p>The backend runs on a Node.js compatible server, which connects to a database such as MongoDB Atlas. The frontend, once it is built, becomes static files that can be hosted from anywhere, from NGINX to hosting platforms like Netlify or Vercel.</p>
<p>This separation provides you with flexibility and improved scalability. Let’s walk through how to deploy each part.</p>
<h3 id="heading-backend-deployment-nodejsexpressjs"><strong>Backend Deployment (Node.js/Express.js)</strong></h3>
<p>For backend deployment, platforms like Heroku, Render, or AWS EC2 are common choices. Here, I’ll outline a general approach for a cloud VM on AWS EC2</p>
<h4 id="heading-1-prepare-for-production">1. Prepare for Production</h4>
<p>To start, set the environment to <code>production</code> and install only the dependencies your app needs to run, optimizing your application's performance. Skipping devDependencies helps reduce its footprint.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">export</span> NODE_ENV=production

npm install --production
</code></pre>
<h4 id="heading-2-process-manager-pm2">2. Process Manager (PM2)</h4>
<p>Next, we’ll set up a process manager to keep our backend server running reliably. PM2 is a popular tool that handles automatic restarts if your Node.js application crashes, manages multiple app instances, and also helps ensure high availability in production environments.</p>
<pre><code class="lang-bash">npm install -g pm2

pm2 start server/app.js --name mern-api

pm2 save

pm2 startup
</code></pre>
<h4 id="heading-3-nginx-as-a-reverse-proxy">3. NGINX as a Reverse Proxy</h4>
<p>Now that our backend is running with PM2, we need a way to handle incoming web traffic. That’s where NGINX comes in. We'll install NGINX to serve as a high-performance reverse proxy directing incoming web traffic to your Node.js backend and serving static frontend files.</p>
<pre><code class="lang-bash">sudo apt update

sudo apt install nginx
</code></pre>
<p>Once NGINX is installed, it’s time to configure it (/etc/nginx/sites-available/default or a new config file). We’ll set it up to forward API requests to the backend and serve the React app, acting as the single entry point. You can update the default configuration file or create a new one:</p>
<pre><code class="lang-nginx"><span class="hljs-comment"># /etc/nginx/sites-available/default</span>
<span class="hljs-section">server</span> {

    <span class="hljs-attribute">listen</span> <span class="hljs-number">80</span>;

    <span class="hljs-attribute">server_name</span> your_domain_or_ip;


    <span class="hljs-attribute">location</span> /api/ {

        <span class="hljs-attribute">proxy_pass</span> http://localhost:5000;

        <span class="hljs-attribute">proxy_http_version</span> <span class="hljs-number">1</span>.<span class="hljs-number">1</span>;

        <span class="hljs-attribute">proxy_set_header</span> Upgrade <span class="hljs-variable">$http_upgrade</span>;

        <span class="hljs-attribute">proxy_set_header</span> Connection <span class="hljs-string">'upgrade'</span>;

        <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$host</span>;

        <span class="hljs-attribute">proxy_cache_bypass</span> <span class="hljs-variable">$http_upgrade</span>;

    }


    <span class="hljs-attribute">location</span> / {

        <span class="hljs-attribute">root</span> /var/www/my-mern-app/client/build; <span class="hljs-comment"># Path to your React build folder</span>

        <span class="hljs-attribute">try_files</span> <span class="hljs-variable">$uri</span> /index.html;

    }

}
</code></pre>
<p>With the NGINX configuration created, we’ll enable it and restart the service to apply the changes, making your application go live:</p>
<pre><code class="lang-bash">sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/

sudo systemctl restart nginx
</code></pre>
<h4 id="heading-4-https-with-certbot-lets-encrypt">4. HTTPS with Certbot (Let's Encrypt)</h4>
<p>To secure your app with HTTPS, we can install Certbot and use it to automatically obtain and configure a free SSL/TLS certificate from Let’s Encrypt, enabling secure HTTPS connections for your domain.</p>
<pre><code class="lang-bash">sudo snap install --classic certbot

sudo certbot --nginx -d your_domain_or_ip
</code></pre>
<h3 id="heading-frontend-deployment-react"><strong>Frontend Deployment (React)</strong></h3>
<p>With the backend deployed, let’s move to the frontend. For the React frontend, we’ll build the application and serve the static files via NGINX (as shown above) or a dedicated static site hosted on platforms like Netlify, Vercel, or AWS S3 + CloudFront.</p>
<h4 id="heading-build-the-react-app">Build the React App</h4>
<p>This command compiles and optimizes your React application into a build folder containing static assets, ready for efficient deployment to any web server or static hosting service.</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> client

npm run build
</code></pre>
<h3 id="heading-database-deployment-mongodb-atlas"><strong>Database Deployment (MongoDB Atlas)</strong></h3>
<p>For production, we’ll use a managed MongoDB service like MongoDB Atlas. It handles replication, sharding, and backups, simplifying database management significantly.</p>
<h4 id="heading-create-a-cluster-on-mongodb-atlas">Create a Cluster on MongoDB Atlas</h4>
<ul>
<li><p>Sign up/Log in to MongoDB Atlas.</p>
</li>
<li><p>Create a new cluster (choose a cloud provider and region).</p>
</li>
<li><p>Set up a database user with appropriate permissions.</p>
</li>
<li><p>Configure network access (allow connections from your server's IP address).</p>
</li>
<li><p>Get your connection string and update MONGO_URI in your server/.env file.</p>
</li>
</ul>
<h4 id="heading-1-env-configuration-example">1. <code>.env</code> Configuration Example</h4>
<p>After creating the cluster and user in MongoDB Atlas, you’ll receive a connection string. You need to update your <code>.env</code> file with it</p>
<pre><code class="lang-ini"><span class="hljs-comment"># server/.env</span>
<span class="hljs-attr">MONGO_URI</span>=mongodb+srv://yourUser:yourPassword@cluster0.mongodb.net/yourDBName
<span class="hljs-attr">JWT_SECRET</span>=your_secret_jwt_key
<span class="hljs-attr">NODE_ENV</span>=production
</code></pre>
<h4 id="heading-2-connect-to-mongodb-in-appjs">2. Connect to MongoDB in <code>app.js</code></h4>
<p>Next, in the <code>server/app.js</code> file, make sure you're using the connection string from the environment variable:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> mongoose = <span class="hljs-built_in">require</span>(<span class="hljs-string">'mongoose'</span>);
<span class="hljs-keyword">const</span> dotenv = <span class="hljs-built_in">require</span>(<span class="hljs-string">'dotenv'</span>);
dotenv.config();

mongoose.connect(process.env.MONGO_URI)
  .then(<span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'MongoDB connected!'</span>))
  .catch(<span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Connection error:'</span>, err));
</code></pre>
<h3 id="heading-other-deployment-options"><strong>Other Deployment Options</strong></h3>
<p>While this article drives you through manual deployment with EC2 and NGINX, other platforms can simplify the process:</p>
<ul>
<li><p><strong>Render</strong>, <strong>Railway</strong>, and <strong>Heroku</strong> offer easy full-stack deployment with GitHub integration.</p>
</li>
<li><p><strong>Vercel</strong> and <strong>Netlify</strong> are ideal for hosting the React frontend.</p>
</li>
<li><p>You may consider using <strong>Docker</strong> to maintain consistent environments across development and production.</p>
</li>
<li><p>For CI/CD, Linting, Testing, &amp; Deployment can be automated on every push using tools like <strong>GitHub Actions</strong></p>
</li>
</ul>
<p>There is no right or wrong choice here. Select the setup that best suits your project’s scale, team experience, and desired level of control.</p>
<h2 id="heading-security-best-practices-fortifying-your-application"><strong>Security Best Practices: Fortifying Your Application</strong></h2>
<p>Security is paramount. You can implement these best practices to protect your MERN application.</p>
<h3 id="heading-setup-input-validation-and-sanitization"><strong>Setup Input Validation and Sanitization</strong></h3>
<p>Always validate and sanitize input on the server side. You can use libraries like Joi or Zod to make this process easier.</p>
<h4 id="heading-example-with-joi">Example with Joi:</h4>
<p>To validate and sanitize incoming data on the server, we will utilize Joi, a powerful library for defining schemas and enforcing input rules.</p>
<pre><code class="lang-bash">npm install joi
</code></pre>
<p>Now that we’ve installed Joi, we will use it to define strict validation rules for user registration and login inputs. This ensures data quality and prevents common injection attacks.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// server/validators/authValidator.js</span>

<span class="hljs-keyword">const</span> Joi = <span class="hljs-built_in">require</span>(<span class="hljs-string">'joi'</span>);


<span class="hljs-keyword">const</span> registerSchema = Joi.object({

  <span class="hljs-attr">username</span>: Joi.string().min(<span class="hljs-number">3</span>).max(<span class="hljs-number">30</span>).required(),

  <span class="hljs-attr">email</span>: Joi.string().email().required(),

  <span class="hljs-attr">password</span>: Joi.string().min(<span class="hljs-number">6</span>).required(),

});


<span class="hljs-keyword">const</span> loginSchema = Joi.object({

  <span class="hljs-attr">email</span>: Joi.string().email().required(),

  <span class="hljs-attr">password</span>: Joi.string().required(),

});


<span class="hljs-built_in">module</span>.exports = { registerSchema, loginSchema };
</code></pre>
<p>Next, we’ll integrate these schemas directly into our authentication controller to automatically validate incoming request bodies against predefined schemas.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// server/controllers/authController.js (snippet)</span>

<span class="hljs-keyword">const</span> { registerSchema, loginSchema } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'../validators/authValidator'</span>);


<span class="hljs-built_in">exports</span>.registerUser = <span class="hljs-keyword">async</span> (req, res) =&gt; {

  <span class="hljs-keyword">const</span> { error } = registerSchema.validate(req.body);

  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">message</span>: error.details[<span class="hljs-number">0</span>].message });

  <span class="hljs-comment">// ... rest of the registration logic</span>

};


<span class="hljs-built_in">exports</span>.loginUser = <span class="hljs-keyword">async</span> (req, res) =&gt; {

  <span class="hljs-keyword">const</span> { error } = loginSchema.validate(req.body);

  <span class="hljs-keyword">if</span> (error) <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">message</span>: error.details[<span class="hljs-number">0</span>].message });

  <span class="hljs-comment">// ... rest of the login logic</span>

};
</code></pre>
<h3 id="heading-add-authentication-and-authorization"><strong>Add Authentication and Authorization</strong></h3>
<p>You can use JWTs for authentication and implement middleware for protected routes.</p>
<h4 id="heading-jwt-implementation-covered-in-authcontrollerjs-and-authmiddlewarejs-above">JWT Implementation (covered in authController.js and authMiddleware.js above)</h4>
<p>Key aspects:</p>
<ul>
<li><p>HttpOnly Cookies: Store JWTs in HttpOnly cookies to prevent client-side JavaScript access, mitigating XSS attacks.</p>
</li>
<li><p>Secure Flag: Use secure: true in production to ensure cookies are only sent over HTTPS.</p>
</li>
</ul>
<p>These practices ensure that authentication tokens are securely transmitted and stored, protecting against common web vulnerabilities like Cross-Site Scripting (XSS).</p>
<h3 id="heading-implement-rate-limiting"><strong>Implement Rate Limiting</strong></h3>
<p>To protect our API from abuse and malicious intent, we will implement basic rate limiting. This helps protect against brute-force login attempts and DDoS attacks.</p>
<h4 id="heading-installation">Installation</h4>
<p>We will install express-rate-limit package for it</p>
<pre><code class="lang-bash">npm install express-rate-limit
</code></pre>
<h4 id="heading-serverappjs-snippet">server/app.js (snippet)</h4>
<p>Once it is installed, let’s configure the rate limiter and apply it to all incoming requests. This ensures that no single IP can overwhelm your server with repeated calls. The following middleware limits each IP address to 200 requests within a 15-minute window.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> rateLimit = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-rate-limit'</span>);

<span class="hljs-keyword">const</span> limiter = rateLimit({

  <span class="hljs-attr">windowMs</span>: <span class="hljs-number">15</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>, <span class="hljs-comment">// 15 minutes</span>

  <span class="hljs-attr">max</span>: <span class="hljs-number">200</span>, <span class="hljs-comment">// Limit each IP to 200 requests per windowMs</span>

  <span class="hljs-attr">message</span>: <span class="hljs-string">'Too many requests from this IP, please try again after 15 minutes'</span>,

});

app.use(limiter); <span class="hljs-comment">// Apply to all requests</span>
</code></pre>
<h3 id="heading-setup-cors-configuration-cross-origin-resource-sharing"><strong>Setup CORS Configuration (Cross-Origin Resource Sharing)</strong></h3>
<p>Next, we move our focus to enable secure communication between your frontend and backend. By default, all browsers block cross-origin requests, so we need to configure CORS (Cross-Origin Resource Sharing) to permit the React app to communicate with the Express API.</p>
<h4 id="heading-installation-1">Installation</h4>
<pre><code class="lang-bash">npm install cors
</code></pre>
<h4 id="heading-serverappjs-snippet-1">server/app.js (snippet)</h4>
<p>Once installed<strong>,</strong> we can configure CORS for our Express application, specifying allowed origins and enabling credential sharing for secure cross-origin requests. Remember to replace the origin with your actual production URL when deploying.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> cors = <span class="hljs-built_in">require</span>(<span class="hljs-string">'cors'</span>);

app.use(cors({

  <span class="hljs-attr">origin</span>: <span class="hljs-string">'http://localhost:3000'</span>, <span class="hljs-comment">// Replace with your frontend URL in production</span>

  <span class="hljs-attr">credentials</span>: <span class="hljs-literal">true</span>,

}));
</code></pre>
<h3 id="heading-use-environment-variables"><strong>Use Environment Variables</strong></h3>
<p>To keep sensitive information secure and out of your codebase, we will use environment variables. This allows us to efficiently manage secrets, such as database connection strings and JWT keys, without hardcoding them or including them in the source code.</p>
<p>Create a <code>.env</code> file in your <code>server/</code> directory:</p>
<h4 id="heading-env-example">.env (example)</h4>
<p>This .env file stores sensitive configuration details like database connection strings and API keys</p>
<pre><code class="lang-ini"><span class="hljs-attr">MONGO_URI</span>=your_mongodb_connection_string

<span class="hljs-attr">JWT_SECRET</span>=your_super_secret_jwt_key

<span class="hljs-attr">NODE_ENV</span>=production
</code></pre>
<h2 id="heading-monitoring-and-logging-with-winston-and-morgan"><strong>Monitoring and Logging with Winston and Morgan</strong></h2>
<p>Once the application is live, it's critical to monitor the behavior and catch issues promptly. Monitoring and logging help you measure performance, find bugs, and keep a log of all server activity.</p>
<p>We’ll use Morgan for logging HTTP requests and Winston for more general-purpose application logging.</p>
<h3 id="heading-installation-2">Installation</h3>
<p>We will install Morgan for logging HTTP requests and Winston for comprehensive and customizable application logging.</p>
<pre><code class="lang-bash">npm install morgan winston
</code></pre>
<h3 id="heading-serverconfigloggerjs">server/config/logger.js</h3>
<p>Next, let’s configure Winston to handle our application logs. This will output logs to the console by default, with options to enable file-based logging for errors and general information.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> winston = <span class="hljs-built_in">require</span>(<span class="hljs-string">'winston'</span>);

<span class="hljs-keyword">const</span> logger = winston.createLogger({

  <span class="hljs-attr">level</span>: <span class="hljs-string">'info'</span>,

  <span class="hljs-attr">format</span>: winston.format.combine(

    winston.format.timestamp(),

    winston.format.json()

  ),

  <span class="hljs-attr">transports</span>: [

    <span class="hljs-keyword">new</span> winston.transports.Console(),

    <span class="hljs-comment">// new winston.transports.File({ filename: 'error.log', level: 'error' }),</span>

    <span class="hljs-comment">// new winston.transports.File({ filename: 'combined.log', level: 'info' }),</span>

  ],

});

<span class="hljs-built_in">module</span>.exports = logger;
</code></pre>
<h3 id="heading-serverappjs-snippet-2">server/app.js (snippet)</h3>
<p>With Winston and Morgan set up, now let’s integrate them into our <code>app.js</code> file. We’ll use Morgan for request logging during development and replace standard <code>console.log</code> calls with Winston logs for structured and configurable application logging.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> morgan = <span class="hljs-built_in">require</span>(<span class="hljs-string">'morgan'</span>);

<span class="hljs-keyword">const</span> logger = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./config/logger'</span>);

<span class="hljs-keyword">if</span> (process.env.NODE_ENV === <span class="hljs-string">'development'</span>) {

  app.use(morgan(<span class="hljs-string">'dev'</span>));

}

<span class="hljs-comment">// Replace console.log with logger.info for database connection</span>

mongoose.connect(process.env.MONGO_URI)

  .then(<span class="hljs-function">() =&gt;</span> logger.info(<span class="hljs-string">'MongoDB connected!'</span>))

  .catch(<span class="hljs-function"><span class="hljs-params">err</span> =&gt;</span> logger.error(<span class="hljs-string">'MongoDB connection error:'</span>, err));


<span class="hljs-comment">// Replace console.log in app.listen</span>

app.listen(PORT, <span class="hljs-function">() =&gt;</span> {

  logger.info(<span class="hljs-string">`Server running on port <span class="hljs-subst">${PORT}</span>`</span>);

});
</code></pre>
<h3 id="heading-frontend-error-monitoring-sentry"><strong>Frontend Error Monitoring (Sentry)</strong></h3>
<p>To monitor errors in the frontend, we’ll integrate Sentry. It’s a fantastic tool for tracking exceptions and performance issues in real time. It helps us capture and report client-side errors.</p>
<h4 id="heading-installation-3">Installation</h4>
<pre><code class="lang-bash">npm install @sentry/react @sentry/tracing
</code></pre>
<h4 id="heading-clientsrcindexjs-snippet">client/src/index.js (snippet)</h4>
<p>After installation, let’s initialize Sentry in the React application so that it can automatically capture errors and performance data. We’ll add this to our <code>index.js</code> file.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> Sentry <span class="hljs-keyword">from</span> <span class="hljs-string">'@sentry/react'</span>;

<span class="hljs-keyword">import</span> { BrowserTracing } <span class="hljs-keyword">from</span> <span class="hljs-string">'@sentry/tracing'</span>;


Sentry.init({

  <span class="hljs-attr">dsn</span>: <span class="hljs-string">"YOUR_SENTRY_DSN"</span>, <span class="hljs-comment">// Replace with your Sentry DSN</span>

  <span class="hljs-attr">integrations</span>: [<span class="hljs-keyword">new</span> BrowserTracing()],

  <span class="hljs-attr">tracesSampleRate</span>: <span class="hljs-number">1.0</span>,

  <span class="hljs-attr">environment</span>: process.env.NODE_ENV,

});
</code></pre>
<p>And that’s it! Congratulations on building and deploying a full-stack MERN app.</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>This article provided a code-first walkthrough of building, securing, and deploying a MERN stack application. By focusing on practical code examples and essential configurations, you now have a solid foundation for your MERN projects.</p>
<p>Remember, continuous learning and adaptation are key in the ever-evolving world of web development. Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Improve and Restructure Your Codebase with AI Tools & Version Control ]]>
                </title>
                <description>
                    <![CDATA[ A codebase can become messy and hard to manage over time. This happens because of quick fixes, outdated features, or just not enough time to clean things up. When code becomes difficult to read or change, it slows down progress and can even cause bug... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/improve-and-restructure-codebase-with-ai-tools/</link>
                <guid isPermaLink="false">6720f7fb2e452955f9433899</guid>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Programming Tips ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ optimization ]]>
                    </category>
                
                    <category>
                        <![CDATA[ improve performance ]]>
                    </category>
                
                    <category>
                        <![CDATA[ version control ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Pull Requests ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oluwadamisi Samuel ]]>
                </dc:creator>
                <pubDate>Tue, 29 Oct 2024 14:58:03 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730194934749/feb606d0-bbbd-43ae-a58c-5932d8c2d76c.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>A codebase can become messy and hard to manage over time. This happens because of quick fixes, outdated features, or just not enough time to clean things up.</p>
<p>When code becomes difficult to read or change, it slows down progress and can even cause bugs. To keep a codebase healthy and easy to work with, you’ll need to take care of it.</p>
<p>Improving and organizing old code can feel like a big task, but there are tools and methods that can make it easier. This guide will show how to refresh your codebase step by step which will make it simpler to work with and less likely to cause issues.</p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-how-to-review-your-code-effectively">How to Review Your Code Effectively</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-identify-technical-debt-and-problem-areas-in-code">How to Identify Technical Debt and Problem Areas in Code</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-measure-code-quality-with-code-analysis-tools">How to Measure Code Quality with Code Analysis Tools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-ai-tools-to-help-you-improve-your-code">AI Tools to Help You Improve Your Code</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-version-control-best-practices-for-code-changes">Version Control Best Practices for Code Changes</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-how-to-review-your-code-effectively">How to Review Your Code Effectively</h2>
<p>Code reviews are essential for catching issues early, improving readability, and ensuring long-term maintainability. Reviewing your own code or someone else’s involves more than just scanning for errors – you’ll also want to make sure each part is clear, efficient, and follows good practices.</p>
<p>Here’s a step-by-step approach to help you review code effectively, with practical strategies, tools, and what to look for during the process.</p>
<h3 id="heading-strategies-for-effective-code-review">Strategies for Effective Code Review</h3>
<ol>
<li><p><strong>Break Down the Review Process:</strong> Reviewing code all at once can be overwhelming, especially in large projects. Focus on small sections of the codebase at a time, such as individual functions or modules. This approach helps you examine each part closely and avoids missing issues that could be overlooked in a quick scan.</p>
</li>
<li><p><strong>Review for Clarity and Simplicity:</strong> Good code should be easy to read and understand. When reading through the code:</p>
<ul>
<li><p><strong>Variable and Function Names:</strong> Are variable names descriptive enough to convey their purpose? Long, unclear names make code harder to follow.</p>
</li>
<li><p><strong>Function Length:</strong> Keep functions short and focused on one task. Long functions are harder to debug and maintain.</p>
</li>
<li><p><strong>Comments and Documentation:</strong> Comments should explain <em>why</em> something is done rather than <em>what</em> is happening, which should be clear from the code itself. For instance, avoid excessive commenting on trivial lines and focus on complex logic or business rules.</p>
</li>
</ul>
</li>
<li><p><strong>Check for Code Reusability and Modularity:</strong> Look for repeated code or functions performing multiple tasks. By modularizing code, you make it easier to test, update, and reuse. In a review, look for:</p>
<ul>
<li><p><strong>Duplicate Code:</strong> Repeated code can often be refactored into a function.</p>
</li>
<li><p><strong>Single Responsibility:</strong> Each function should handle one task, making it easier to maintain and update.</p>
</li>
</ul>
</li>
<li><p><strong>Examine Error Handling and Edge Cases:</strong> Robust code should handle unexpected inputs or errors gracefully. During a review, think about potential edge cases that could break the code:</p>
<ul>
<li><p><strong>Null or Undefined Values:</strong> Does the code check for undefined values where needed?</p>
</li>
<li><p><strong>Out-of-Range Errors:</strong> Ensure array indexes and calculations won’t produce errors with edge cases.</p>
</li>
<li><p><strong>Error Messages:</strong> Make sure error handling is meaningful, with clear error messages where applicable.</p>
</li>
</ul>
</li>
<li><p><strong>Look for Performance Issues:</strong> Performance may not always be critical, but it’s good to check for potential bottlenecks. Look for:</p>
<ul>
<li><p><strong>Loop Optimization:</strong> Avoid deeply nested loops or repeated work inside loops.</p>
</li>
<li><p><strong>Database Queries:</strong> Minimize unnecessary database calls.</p>
</li>
<li><p><strong>Heavy Computation in the Main Thread:</strong> Move any heavy processing outside the main application thread if possible.</p>
</li>
</ul>
</li>
<li><p><strong>Ensure Consistency with Coding Standards:</strong> Following a consistent coding style improves readability across the team. Many teams use linters or style guides to enforce these standards. Look for:</p>
<ul>
<li><p><strong>Code Format:</strong> Consistent indentation, spacing, and use of braces.</p>
</li>
<li><p><strong>Naming Conventions:</strong> Follow agreed naming conventions (camelCase, snake_case, and so on) consistently.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-tools-to-assist-with-code-reviews">Tools to Assist with Code Reviews</h3>
<p>There are a number of tools out there that can help streamline your code reviews, whether you’re checking your own code or collaborating with others:</p>
<h4 id="heading-1-linters-like-eslint-and-pylint"><strong>1. Linters (like ESLint and Pylint)</strong></h4>
<p>Linters check for syntax errors, code smells, and style guide violations. They are especially useful for catching minor issues, like inconsistent formatting or unused variables. We will discuss ESLint more in an upcoming section.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Example: Run ESLint on a JavaScript project</span>
npx eslint src/
</code></pre>
<h4 id="heading-2-static-analysis-tools-like-sonarqube"><strong>2. Static Analysis Tools (like SonarQube)</strong></h4>
<p>These tools analyze code for deeper issues like security vulnerabilities, code duplication, and complex functions that might need refactoring.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Configuring SonarQube to scan a project</span>
sonar.projectKey=my_project
sonar.sources=src
sonar.host.url=http://localhost:9000
sonar.login=my_token
</code></pre>
<h4 id="heading-3-automated-testing-tools"><strong>3. Automated Testing Tools</strong></h4>
<p>Running tests can verify that code changes don’t introduce new bugs. Use testing frameworks like Jest for JavaScript, PyTest for Python, or JUnit for Java to confirm your code behaves as expected.</p>
<h3 id="heading-example-of-refactoring-during-code-review">Example of Refactoring During Code Review</h3>
<p>Let’s say you encounter a long function with multiple responsibilities. The goal is to split it into smaller, focused functions. Here’s how you can do that:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Original: A single function that handles everything</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processOrder</span>(<span class="hljs-params">order</span>) </span>{
    <span class="hljs-comment">// Calculate total price</span>
    <span class="hljs-keyword">let</span> total = <span class="hljs-number">0</span>;
    order.items.forEach(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> {
        total += item.price * item.quantity;
    });

    <span class="hljs-comment">// Apply discount</span>
    <span class="hljs-keyword">if</span> (order.discountCode) {
        total = total * <span class="hljs-number">0.9</span>; <span class="hljs-comment">// 10% discount</span>
    }

    <span class="hljs-comment">// Send order confirmation email</span>
    sendEmail(order.customerEmail, <span class="hljs-string">'Order Confirmation'</span>, <span class="hljs-string">'Your order total is '</span> + total);
}

<span class="hljs-comment">// Improved: Break into smaller functions for readability and reusability</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateTotal</span>(<span class="hljs-params">order</span>) </span>{
    <span class="hljs-keyword">return</span> order.items.reduce(<span class="hljs-function">(<span class="hljs-params">sum, item</span>) =&gt;</span> sum + item.price * item.quantity, <span class="hljs-number">0</span>);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">applyDiscount</span>(<span class="hljs-params">total, discountCode</span>) </span>{
    <span class="hljs-keyword">return</span> discountCode ? total * <span class="hljs-number">0.9</span> : total;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sendConfirmationEmail</span>(<span class="hljs-params">email, total</span>) </span>{
    sendEmail(email, <span class="hljs-string">'Order Confirmation'</span>, <span class="hljs-string">'Your order total is '</span> + total);
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processOrder</span>(<span class="hljs-params">order</span>) </span>{
    <span class="hljs-keyword">let</span> total = calculateTotal(order);
    total = applyDiscount(total, order.discountCode);
    sendConfirmationEmail(order.customerEmail, total);
}
</code></pre>
<p>Breaking down the process into smaller functions makes the code cleaner, more readable, and easier to test. Each function now has a single responsibility, which helps reduce bugs and makes future updates simpler.</p>
<h2 id="heading-how-to-identify-technical-debt-and-problem-areas-in-code">How to Identify Technical Debt and Problem Areas in Code</h2>
<p>Technical debt refers to the accumulation of issues within a codebase that arise when development shortcuts are taken, often to meet tight deadlines or speed up releases. While these shortcuts may enable quicker progress initially, they lead to complications down the line.</p>
<p>Technical debt requires proactive management. If you leave it unchecked, it can reduce productivity, create bugs, and slow down development.</p>
<p>Think of technical debt like financial debt: taking on debt can be helpful in the short term, but failing to address it or pay it down will lead to greater challenges.</p>
<p>Common causes of technical debt include:</p>
<ul>
<li><p><strong>Rushed development cycles:</strong> When teams prioritize quick delivery over thorough design and testing, they may produce incomplete or hastily written code.</p>
</li>
<li><p><strong>Lack of planning for future changes:</strong> Sometimes, code is written without accounting for scalability, leading to issues as the project grows.</p>
</li>
<li><p><strong>Insufficient documentation or testing:</strong> Without proper documentation and test coverage, codebases become difficult to understand and validate over time.</p>
</li>
<li><p><strong>Outdated frameworks and dependencies:</strong> When frameworks or libraries aren’t updated, they can become incompatible with newer components or security standards, introducing risk and hindering future updates.</p>
</li>
</ul>
<h3 id="heading-types-of-technical-debt">Types of Technical Debt</h3>
<p>Technical debt manifests in different ways. Here are some common examples:</p>
<p><strong>1. Code Duplication:</strong></p>
<p>Repeated code across multiple places within a project can lead to inconsistencies, as fixing an issue or updating a feature in one area may not carry over to others. Refactoring duplicate code into reusable functions or components is an effective way to reduce this debt.</p>
<p><strong>Example:</strong> In a web application, you might find similar code for user authentication scattered across different modules. Instead, centralizing this logic into a single authentication module ensures consistent updates.</p>
<p><strong>2. Outdated Dependencies and Frameworks:</strong></p>
<p>Using old libraries or frameworks can slow down development and introduce security vulnerabilities. Over time, dependencies may lose support or become incompatible with new features, making them costly to maintain.</p>
<p><strong>Solution:</strong> Regularly update libraries and frameworks, and monitor for deprecations or vulnerabilities. This can be streamlined by using dependency managers, which help check for updates and security patches.</p>
<p><strong>3. Complex, Long Functions with Multiple Responsibilities:</strong></p>
<p>Large, complex functions that handle multiple tasks are difficult to understand, test, and modify. Known as “God functions,” these make debugging cumbersome and increase the risk of introducing new bugs.</p>
<p><strong>Solution:</strong> Follow the <strong>Single Responsibility Principle (SRP)</strong>. This means that each function or method should accomplish one task. Breaking down large functions into smaller, focused units makes the code easier to read and test.</p>
<p><strong>Example:</strong> Instead of having a single <code>processUserRequest</code> function that handles authentication, logging, and database queries, split it into three functions: <code>authenticateUser</code>, <code>logRequest</code>, and <code>queryDatabase</code>.</p>
<p><strong>4. Insufficient Error Handling:</strong></p>
<p>Code that lacks proper error handling can lead to bugs and unexpected behavior, especially in larger systems. Without clear error messages, diagnosing and fixing issues can be challenging.</p>
<p><strong>Solution:</strong> Include comprehensive error handling and ensure that meaningful error messages are displayed. Log errors in a way that helps developers track and diagnose issues.</p>
<p><strong>5. Hardcoded Values:</strong></p>
<p>Hardcoding values directly into code makes it difficult to adjust settings without modifying the source code. For example, using fixed URLs or credentials directly in the codebase can create security risks and maintenance headaches.</p>
<p><strong>Solution:</strong> Use configuration files or environment variables to store values that might change. This improves security and allows for easy updates.</p>
<p><strong>6. Lack of Documentation and Testing:</strong></p>
<p>Documentation and testing are often neglected when time is short. But without proper documentation and test coverage, the code becomes challenging to understand and validate, slowing down development and increasing the risk of bugs.</p>
<p><strong>Solution:</strong> Implement test-driven development (TDD) or include time in the development cycle for creating documentation and writing tests. Aim for at least basic test coverage for critical paths and functions.</p>
<h3 id="heading-how-to-identify-and-manage-technical-debt">How to Identify and Manage Technical Debt</h3>
<p>Identifying technical debt is crucial if you want to address and improve it. Here are some strategies you can follow:</p>
<ol>
<li><p><strong>Code Reviews:</strong> Regular peer reviews help uncover areas of potential debt. In reviews, team members can flag complex code, lack of tests, or unclear logic, helping address these issues early.</p>
</li>
<li><p><strong>Automated Static Code Analysis:</strong> Tools like SonarQube, Code Climate, and ESLint (for JavaScript) analyze codebases for code smells, vulnerabilities, and complexity. They’re effective for spotting issues like duplicate code, long functions, and outdated dependencies.</p>
</li>
<li><p><strong>Regular Refactoring Sessions:</strong> Scheduling dedicated time for refactoring allows the team to improve existing code quality. During these sessions, focus on simplifying code, breaking down large functions, and removing duplicates.</p>
</li>
<li><p><strong>Technical Debt Backlog:</strong> Track technical debt items in a backlog, prioritizing them alongside feature development. This backlog helps balance feature work with debt reduction and keeps everyone aware of existing debt.</p>
</li>
</ol>
<h3 id="heading-how-to-deal-with-technical-debt-in-code">How to Deal with Technical Debt in Code</h3>
<p>Here’s a practical example to demonstrate how refactoring can help address technical debt, specifically by removing code duplication.</p>
<h4 id="heading-example-removing-duplicate-code">Example: Removing Duplicate Code</h4>
<p>Let’s say we have two functions that send different types of emails but use repeated code:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Duplicate code example</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_welcome_email</span>(<span class="hljs-params">user</span>):</span>
    send_email(user.email, <span class="hljs-string">"Welcome!"</span>, <span class="hljs-string">"Thanks for joining!"</span>)

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_password_reset_email</span>(<span class="hljs-params">user</span>):</span>
    send_email(user.email, <span class="hljs-string">"Password Reset"</span>, <span class="hljs-string">"Click here to reset your password."</span>)
</code></pre>
<p>Each function has a similar structure, so refactoring can make the code cleaner and reduce duplication.</p>
<pre><code class="lang-python"><span class="hljs-comment"># Refactored code</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">send_email_to_user</span>(<span class="hljs-params">user, subject, message</span>):</span>
    send_email(user.email, subject, message)

<span class="hljs-comment"># Use the refactored function</span>
send_email_to_user(new_user, <span class="hljs-string">"Welcome!"</span>, <span class="hljs-string">"Thanks for joining!"</span>)
send_email_to_user(existing_user, <span class="hljs-string">"Password Reset"</span>, <span class="hljs-string">"Click here to reset your password."</span>)
</code></pre>
<p>This example demonstrates how consolidation can reduce repetition and make the code more flexible.</p>
<h3 id="heading-how-to-avoid-technical-debt">How to Avoid Technical Debt</h3>
<p>Proactively managing technical debt helps reduce it over time. Here are ways to avoid accumulating more debt:</p>
<ul>
<li><p><strong>Establish Code Standards:</strong> Create and enforce coding standards within the team. Consistent practices reduce complexity, improve readability, and make it easier to identify issues early.</p>
</li>
<li><p><strong>Refactor Regularly:</strong> Rather than waiting for debt to accumulate, make minor improvements during routine work. A “leave it better than you found it” approach ensures code quality remains high over time.</p>
</li>
<li><p><strong>Encourage Thorough Testing:</strong> Strong test coverage identifies potential problems early, reducing the likelihood of code with hidden issues. Testing tools like Jest for JavaScript or PyTest for Python make it easy to add tests to each function and module.</p>
</li>
<li><p><strong>Plan for Scalability:</strong> Think about future needs when designing code. Avoid shortcuts that might restrict scalability and performance as the application grows.</p>
</li>
<li><p><strong>Limit Workarounds and Temporary Fixes:</strong> If temporary fixes are necessary, document them and prioritize removing them as soon as possible. Keeping track of these “quick fixes” ensures they don’t become long-term issues.</p>
</li>
</ul>
<h2 id="heading-how-to-measure-code-quality-with-code-analysis-tools">How to Measure Code Quality with Code Analysis Tools</h2>
<p>Code quality tools can help you find issues that might not be obvious. They can point out things like unused variables, code that’s hard to read, or security problems. Popular tools include <code>ESLint</code> for <code>JavaScript</code>, <code>Pylint</code> for <code>Python</code>, and <code>SonarQube</code> for different programming languages.</p>
<p>Here’s how to set up a simple code check with ESLint:</p>
<ol>
<li><p><strong>Install ESLint</strong>:</p>
<pre><code class="lang-bash"> npm install eslint --save-dev
</code></pre>
</li>
<li><p><strong>Initialize ESLint</strong>:</p>
<pre><code class="lang-bash"> npx eslint --init
</code></pre>
<p> This command will prompt you to answer a few configuration questions. You can choose your preferred style guide and select a few options about your environment and file format.</p>
</li>
<li><p><strong>Example Code with Issues</strong></p>
<p> Here’s a sample JavaScript file (<code>example.js</code>) with a few common issues:</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// example.js</span>

 <span class="hljs-keyword">var</span> x = <span class="hljs-number">10</span>;   <span class="hljs-comment">// Unused variable</span>
 <span class="hljs-keyword">let</span> y = <span class="hljs-number">5</span>;
 <span class="hljs-keyword">const</span> z = <span class="hljs-string">'Hello World'</span>

 <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateSum</span>(<span class="hljs-params">a, b</span>) </span>{
     <span class="hljs-keyword">return</span> a + b
 }

 calculateSum(<span class="hljs-number">3</span>, <span class="hljs-number">4</span>);

 <span class="hljs-comment">// Missing semicolon and inconsistent indentation</span>
 <span class="hljs-keyword">if</span>(y &gt; <span class="hljs-number">3</span>){
     <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Y is greater than 3"</span>)
 }
</code></pre>
</li>
<li><p><strong>Run ESLint</strong>:</p>
<pre><code class="lang-bash"> npx eslint example.js
</code></pre>
<p> After running this command, ESLint will analyze <code>example.js</code> and report any issues based on the configured rules.</p>
</li>
<li><p><strong>ESLint Output</strong></p>
<p> ESLint provides detailed feedback about the issues it detects:</p>
<pre><code class="lang-plaintext"> /path/to/example.js
   1:5  warning  'x' is assigned a value but never used          no-unused-vars
   3:12  error    Missing semicolon                               semi
   6:25  error    Missing semicolon                               semi
   10:1  error    Expected indentation of 4 spaces but found 3    indent
   11:26 error    Missing semicolon                               semi

 ✖ 5 problems (4 errors, 1 warning)
</code></pre>
<p> Here’s a breakdown of each issue detected by ESLint:</p>
<ul>
<li><p><strong>Unused Variable</strong>: ESLint identifies that <code>x</code> is declared but never used (<code>no-unused-vars</code> rule).</p>
</li>
<li><p><strong>Missing Semicolons</strong>: ESLint flags lines where semicolons are missing at the end of statements (<code>semi</code> rule).</p>
</li>
<li><p><strong>Inconsistent Indentation</strong>: ESLint notices that line 10 doesn’t follow consistent indentation (<code>indent</code> rule).</p>
</li>
</ul>
</li>
<li><p><strong>Fixing the Code</strong></p>
<p> Based on ESLint’s feedback, here’s the corrected code:</p>
<pre><code class="lang-javascript"> <span class="hljs-comment">// example.js</span>

 <span class="hljs-keyword">let</span> y = <span class="hljs-number">5</span>;
 <span class="hljs-keyword">const</span> z = <span class="hljs-string">'Hello World'</span>;

 <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateSum</span>(<span class="hljs-params">a, b</span>) </span>{
     <span class="hljs-keyword">return</span> a + b;
 }

 calculateSum(<span class="hljs-number">3</span>, <span class="hljs-number">4</span>);

 <span class="hljs-keyword">if</span> (y &gt; <span class="hljs-number">3</span>) {
     <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Y is greater than 3"</span>);
 }
</code></pre>
<ul>
<li><p>We removed the unused variable <code>x</code>.</p>
</li>
<li><p>We added missing semicolons.</p>
</li>
<li><p>And we adjusted indentation for consistent spacing.</p>
</li>
</ul>
</li>
<li><p><strong>Re-run ESLint to Verify Fixes</strong></p>
<p> After making these changes, you can run <code>npx eslint example.js</code> again to confirm that there are no remaining issues. ESLint will return no output if everything is now clean, confirming that the code adheres to the configured standards.</p>
</li>
</ol>
<h3 id="heading-additional-tip-auto-fixing-with-eslint">Additional Tip: Auto-Fixing with ESLint</h3>
<p>ESLint can automatically fix some issues for you. To do this, use the <code>--fix</code> flag:</p>
<pre><code class="lang-bash">npx eslint example.js --fix
</code></pre>
<p>This command will automatically correct issues like indentation, unused variables, and missing semicolons where possible. But it’s important to review the changes to ensure they align with your intended functionality.</p>
<p>Reviewing code, spotting technical debt, and using quality tools help keep the codebase healthy. If you follow these steps, your project will be easier to manage and less likely to break.</p>
<h2 id="heading-ai-tools-to-help-you-improve-your-code">AI Tools to Help You Improve Your Code</h2>
<p>Using AI tools to restructure code makes improving code quality much faster and easier. These tools help find issues, suggest changes, and can even automate some parts of the refactoring process.</p>
<p>I'll share some AI tools that can help you with code analysis, refactoring, and dependency management, based on my own experience and what I've found useful.</p>
<h3 id="heading-best-ai-tools-for-code-restructuring">Best AI Tools for Code Restructuring</h3>
<p>AI-powered tools are becoming more common, and they offer different ways to boost code quality and simplify refactoring. Here are some I've found helpful:</p>
<h4 id="heading-1-github-copilot"><strong>1. GitHub Copilot</strong></h4>
<p>GitHub Copilot is like a coding assistant that provides smart suggestions as you write code. It can complete code snippets, suggest new functions, and help rework existing code to make it more efficient. I’ve found it useful for writing repetitive code blocks or coming up with quick refactorings.</p>
<p>For example, let’s say you need to rewrite a function to be more efficient:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Original function that checks if a number is prime</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">is_prime</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">if</span> n &lt; <span class="hljs-number">2</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">2</span>, n):
        <span class="hljs-keyword">if</span> n % i == <span class="hljs-number">0</span>:
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
</code></pre>
<p>GitHub Copilot might suggest optimizing the function like this:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Optimized version suggested by Copilot</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">is_prime</span>(<span class="hljs-params">n</span>):</span>
    <span class="hljs-keyword">if</span> n &lt; <span class="hljs-number">2</span>:
        <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">2</span>, int(n**<span class="hljs-number">0.5</span>) + <span class="hljs-number">1</span>):
        <span class="hljs-keyword">if</span> n % i == <span class="hljs-number">0</span>:
            <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span>
    <span class="hljs-keyword">return</span> <span class="hljs-literal">True</span>
</code></pre>
<p>The updated version checks factors only up to the square root of <code>n</code>, making it faster for large numbers.</p>
<h4 id="heading-2-qodogen"><strong>2. QodoGen</strong></h4>
<p>QodoGen provides automated suggestions for refactoring and can detect common code issues, like unused variables or large functions doing too many tasks. It also helps split complex code into smaller, more manageable pieces and can explain sections of the code base or the entire codebase which will facilitate the restructuring process.</p>
<p>This tool is capable of doing this because, unlike other AI assistants and general purpose code generation tools, Qodo focuses on code integrity, while generating tests that help you understand how your code behaves. This can help you discover edge cases and suspicious behaviors, and make your code more robust.</p>
<p>For example, if you have a function handling multiple tasks, QodoGen might suggest breaking it down:</p>
<pre><code class="lang-python"><span class="hljs-comment"># Before refactoring</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">handle_user_data</span>(<span class="hljs-params">user_data</span>):</span>
    validate_data(user_data)
    save_to_database(user_data)
    send_welcome_email(user_data)

<span class="hljs-comment"># After refactoring</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">handle_user_data</span>(<span class="hljs-params">user_data</span>):</span>
    validated_data = validate_data(user_data)
    save_data(validated_data)
    notify_user(validated_data)
</code></pre>
<p>Separating the steps makes the code easier to maintain and test.</p>
<h4 id="heading-3-chatgpt-for-code-assistance"><strong>3. ChatGPT for Code Assistance</strong></h4>
<p>ChatGPT can act as a helpful companion when working on code restructuring tasks. Arguably the most used coding assistant, it provides advice on refactoring strategies, explains how to implement changes, or offers example snippets. It’s like having an expert to consult whenever you need guidance or ideas.</p>
<p>For instance, if you’re unsure how to optimize a function or restructure a class, ChatGPT can provide sample code or describe best practices. You can also ask it for help with understanding errors or fixing specific problems in your code.</p>
<p>Just make sure you double-check the code it provides (same goes for all these AI assistants) as it can hallucinate and make mistakes.</p>
<h3 id="heading-automated-tools-for-refactoring-and-analysis">Automated Tools for Refactoring and Analysis</h3>
<p>AI tools not only assist with writing code but also with analyzing it for quality improvements:</p>
<h4 id="heading-1-sonarqube"><strong>1. SonarQube</strong></h4>
<p>SonarQube scans the code to detect bugs, vulnerabilities, and code smells. It generates reports with suggestions on what to fix, helping maintain a healthy codebase.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Sample SonarQube configuration</span>
sonar.projectKey=my_project
sonar.sources=src
sonar.host.url=http://localhost:9000
sonar.login=my_token
</code></pre>
<h4 id="heading-2-resharper"><strong>2. ReSharper</strong></h4>
<p>This tool integrates with Visual Studio and offers automatic refactoring options. It highlights code that can be simplified or cleaned up and suggests ways to optimize the codebase.</p>
<h4 id="heading-3-depcheck-for-dependency-management"><strong>3. DepCheck for Dependency Management</strong></h4>
<p>AI tools like DepCheck help find unused dependencies in JavaScript projects, keeping package files clean.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Running DepCheck to find unused dependencies</span>
npx depcheck
</code></pre>
<h3 id="heading-how-these-tools-help-with-code-restructuring">How These Tools Help with Code Restructuring</h3>
<p>Using AI tools like GitHub Copilot, QodoGen, and ChatGPT speeds up the process of code restructuring. They provide suggestions that save time and catch issues early, making the code easier to maintain.</p>
<p>Combining these tools with automated analysis tools like SonarQube and ReSharper ensures all aspects of the codebase are covered, from quality checks to refactoring.</p>
<p>These AI tools have other features that facilitate this process: for example, they all have a chat feature that lets you ask questions and get replies about your code and any best practices you should be following. Also, QodoGen allows you to add parts of or the whole codebase for context with the click of a button, along with other features for test generation and pull request reviews.</p>
<p>When restructuring your codebase, having a variety of AI tools can make the process smoother and more efficient. This is AI usage at its best.</p>
<h2 id="heading-version-control-best-practices-for-code-changes">Version Control Best Practices for Code Changes</h2>
<p>Version control keeps track of code changes, making it easier to manage updates, collaborate with others, and fix issues. Following some best practices can help maintain a clean and organized codebase.</p>
<p>Let’s look at how to manage code changes, track updates, and ensure quality through code reviews.</p>
<h3 id="heading-using-git-branching-strategies-to-manage-code-changes">Using Git Branching Strategies to Manage Code Changes</h3>
<p>Git branching helps keep different versions of the code separate, allowing multiple developers to work without affecting the main codebase. Here are some common strategies:</p>
<h4 id="heading-1-feature-branching"><strong>1. Feature Branching</strong></h4>
<p>Feature branches allow developers to work on a new feature without changing the main codebase. Each feature gets its own branch, and once complete, it can be merged into the main branch.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Creating a new feature branch</span>
git checkout -b feature/new-login-page

<span class="hljs-comment"># Working on the new feature and then committing changes</span>
git add .
git commit -m <span class="hljs-string">"Added login page UI"</span>

<span class="hljs-comment"># Merging the feature branch into the main branch</span>
git checkout main
git merge feature/new-login-page
</code></pre>
<h4 id="heading-2-gitflow-strategy"><strong>2. GitFlow Strategy</strong></h4>
<p>This strategy involves using multiple branches for different stages of development, such as feature, develop, and release. It separates development work and allows smoother integration and deployment.</p>
<ul>
<li><p><strong>Main Branch</strong>: Contains production-ready code.</p>
</li>
<li><p><strong>Develop Branch</strong>: Holds the latest completed work, ready for the next release.</p>
</li>
<li><p><strong>Feature Branches</strong>: Created from the develop branch for new features.</p>
</li>
</ul>
<p>Example:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Switch to the develop branch</span>
git checkout develop

<span class="hljs-comment"># Create a new branch for a feature</span>
git checkout -b feature/upgrade-search

<span class="hljs-comment"># Commit changes and push the feature branch</span>
git add .
git commit -m <span class="hljs-string">"Improved search feature"</span>
git push origin feature/upgrade-search
</code></pre>
<h3 id="heading-how-to-track-and-document-code-updates">How to Track and Document Code Updates</h3>
<p>Documenting code changes helps keep the team informed and makes it easier to understand what was done later. Here are some tips for tracking updates:</p>
<h4 id="heading-1-writing-clear-commit-messages"><strong>1. Writing Clear Commit Messages</strong></h4>
<p>Commit messages should explain what was changed and why. A clear message helps others know the purpose of each update.</p>
<p>Example:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Good commit message</span>
git commit -m <span class="hljs-string">"Fixed bug that caused login failure on mobile devices"</span>

<span class="hljs-comment"># Bad commit message</span>
git commit -m <span class="hljs-string">"Fixed bug"</span>
</code></pre>
<h4 id="heading-2-using-tags-to-mark-releases"><strong>2. Using Tags to Mark Releases</strong></h4>
<p>Tags can be used to label important points in the project’s history, such as release versions. This makes it easier to find stable versions of the code.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create a tag for version 1.0</span>
git tag v1.0

<span class="hljs-comment"># Push the tag to the remote repository</span>
git push origin v1.0
</code></pre>
<h4 id="heading-3-creating-and-using-changelogs"><strong>3. Creating and Using Changelogs</strong></h4>
<p>A changelog lists the changes made in each version, helping developers and users see what was updated or fixed.</p>
<p>Example format for a changelog:</p>
<pre><code class="lang-plaintext">## [1.0.1] - 2024-10-01
### Added
- New login feature

### Fixed
- Resolved search issue on homepage

### Changed
- Updated user dashboard layout
</code></pre>
<h3 id="heading-importance-of-code-reviews-in-maintaining-code-quality">Importance of Code Reviews in Maintaining Code Quality</h3>
<p>Code reviews help catch errors, share knowledge, and ensure code stays clean and maintainable. Here are some practices to follow for effective code reviews:</p>
<h4 id="heading-1-keep-code-changes-small"><strong>1. Keep Code Changes Small</strong></h4>
<p>Smaller changes are easier to review, making it more likely to spot mistakes. Large changes can be broken down into smaller parts.</p>
<h4 id="heading-2-use-pull-requests-for-reviews"><strong>2. Use Pull Requests for Reviews</strong></h4>
<p>Pull requests create a space for discussion around changes. Team members can review the changes, suggest improvements, and approve the updates.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Push the feature branch to the remote repository</span>
git push origin feature/new-feature

<span class="hljs-comment"># Create a pull request on GitHub, GitLab, or Bitbucket</span>
</code></pre>
<h4 id="heading-3-provide-constructive-feedback"><strong>3. Provide Constructive Feedback</strong></h4>
<p>Code reviews should aim to improve the code without discouraging the developer. Suggest better ways to solve problems and explain the reasoning.</p>
<p>Example comments during a code review:</p>
<ul>
<li><p>"Consider using a list instead of a dictionary for this data structure, as it simplifies the code."</p>
</li>
<li><p>"This function is doing multiple tasks. It might be clearer if we split it into two separate functions."</p>
</li>
</ul>
<p>Using these practices helps ensure code changes are managed effectively, updates are well-documented, and the quality of the codebase remains high. Regular code reviews and proper branching strategies make it easier for teams to collaborate and keep the project on track.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Reviving and restructuring a codebase can seem like a big task, but taking small, planned steps makes it manageable. Start by checking the current state of the code and making a list of areas that need work. Set clear goals and create a plan to improve the code, step by step.</p>
<p>Using the tools we discussed here can help find issues, suggest changes, and even automate some tasks. Version control practices, such as branching strategies and code reviews, keep changes organized and ensure the quality stays high.</p>
<p>With a solid approach, even the messiest codebase can become clean, efficient, and easier to work with.</p>
<h3 id="heading-resources">Resources</h3>
<ul>
<li><p>AI tools have been developed to assist with the Git branching, Pull Request reviews and approval. Check out <a target="_blank" href="https://dev.to/oluwadamisisamuel1/merge-mastery-elevating-your-pull-request-game-in-open-source-projects-25fo">this article</a> to read more on one of my favorites.</p>
</li>
<li><p>If you want a step by step tutorial on how to revive and refactor your code, check out <a target="_blank" href="https://youtu.be/yMQJUaUtiJo?si=CGd2WBcD117p7lrS">this youtube video</a>.</p>
</li>
<li><p>Check out <a target="_blank" href="https://www.freecodecamp.org/news/best-practices-for-refactoring-code/">this freecodecamp article</a> on code restructuring to dive deeper.</p>
</li>
</ul>
<p>Connect with me on <a target="_blank" href="https://www.linkedin.com/in/samuel-oluwadamisi-01b3a4236/?lipi=urn%3Ali%3Apage%3Ad_flagship3_feed%3BxAUJMbSgQTeDtb7n2d0mQQ%3D%3D">LinkedIn</a>, <a target="_blank" href="https://twitter.com/Data_Steve_">Twitter</a>, and <a target="_blank" href="https://dev.to/dashboard">my peronal blog</a> if you found this helpful.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ React Best Practices Ever Developer Should Know ]]>
                </title>
                <description>
                    <![CDATA[ The more I study React.js, the more I fall in love with it. No doubt that it’s one of the most useful and loved front-end JavaScript libraries out there. And the improvements that the React team have made lately don’t just affect developers, but also... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/react-best-practices-ever-developer-should-know/</link>
                <guid isPermaLink="false">66fecb8f0c5ac3f56463c16b</guid>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Prankur Pandey ]]>
                </dc:creator>
                <pubDate>Thu, 03 Oct 2024 16:51:27 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727898200192/2b6b5882-f4e7-4cb5-9f97-4974669825fc.webp" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>The more I study React.js, the more I fall in love with it. No doubt that it’s one of the most useful and loved front-end JavaScript libraries out there. And the improvements that the React team have made lately don’t just affect developers, but also those who use applications built with React.</p>
<p><a target="_blank" href="https://www.freecodecamp.org/news/learn-react-hooks-with-example-code/">In a previous article</a>, I talked about various React Hooks and how they work along with code samples and detailed explanations.</p>
<p>In this guide, I’m going to talk about some important things that I’ve learned while developing React apps. And these learnings are optimized based on using React Hooks. We’ll debunk some common myths, simplify common concepts, and optimize your code for the best performance.</p>
<h3 id="heading-what-well-cover">What we’ll cover:</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-will-this-guide-benefit-you">How Will This Guide Benefit You?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-prerequsites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-react-state-must-be-immutable">React State Must Be Immutable</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-dont-use-state-for-everything">Don't Use State for Everything</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-derive-values-without-state">Derive Values Without State</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-compute-values-without-effects">Compute Values Without Effects</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-keys-should-be-unique">Keys Should Be Unique</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-use-useeffect-last">Use useEffect Last</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion:</a></p>
</li>
</ul>
<h2 id="heading-how-will-this-guide-benefit-you">How Will This Guide Benefit You?</h2>
<p>Let’s say you have a knife and I ask you to cut out some shapes from a piece of cloth. You could do it, but it would take a while and be challenging using a knife. Instead, what if I gave you a pair of really sharp scissors and then asked you to cut out the patterns? It’d be much easier, right?</p>
<p>This guide is like that optimised approach of cutting cloth with scissors instead of a knife. I’ll teach you how to use React more easily, without as much struggle. We’ll discuss the important aspects of how React Hooks work, and we’ll also cover some do’s &amp; don’ts.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>There is only one main prerequisite for following this guide: you should have used React hooks at least once. And by this I mean developed an application with React that leverages the power of hooks.</p>
<p>This article is for everyone who wishes to use React hooks to their full potential.</p>
<h2 id="heading-react-state-must-be-immutable">React State Must Be Immutable</h2>
<p>Have you ever wondered why React makes such a fuss about immutability? 🤔 As a newbie, you might think that JavaScript's mutations are perfectly fine. After all, we add or remove properties from objects and manipulate arrays with ease.</p>
<p>But here's the twist: in React, immutability isn't about never changing state, it's about ensuring consistency.</p>
<p>When you mutate state directly, React can’t detect changes reliably. This means your UI might not update as expected. The trick? Replace old data with new copies.</p>
<p>For instance, if you need to add a user, you should create a new array with the new user included, rather than pushing directly into the existing array.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> updatedUsers = [...users, newUser];
</code></pre>
<p>The code <code>const updatedUsers = [...users, newUser];</code> uses the spread operator to create a new array, <code>updatedUsers</code>, which combines the existing <code>users</code> with <code>newUser</code>.</p>
<p>This approach maintains immutability in React by not modifying the original <code>users</code> array. Instead, it creates a new state representation, allowing React to optimize rendering and ensure predictable state changes. When you update the state using <code>setUsers(updatedUsers);</code>, React re-renders the component based on this new array, adhering to best practices for state management.</p>
<p>This ensures React detects the change and re-renders your component smoothly.</p>
<h2 id="heading-dont-use-usestate-for-everything">Don't Use <code>useState</code> for Everything</h2>
<p>Confession time: I used to throw everything into <code>useState</code> without thinking twice. 🚀 But here's the scoop: not everything needs to be in state. The state is powerful, but overusing it can lead to complex and inefficient code.</p>
<p>Consider alternatives like server state, URL state, or local storage. For server data, libraries like React Query are a game changer. They handle fetching and caching so you don’t have to manage it manually. For URL state, leverage hooks like <code>useLocation</code> from React Router or Next.js’s built-in methods.</p>
<p>Checklist before using useState:</p>
<ul>
<li><p>Is this value simple and derivable during render?</p>
</li>
<li><p>Does a library already manage this state?</p>
</li>
<li><p>Does it need to trigger a re-render?</p>
</li>
<li><p>If you answer “no” to all, you might not need <code>useState</code> at all.</p>
</li>
</ul>
<h2 id="heading-derive-values-without-state">Derive Values Without State</h2>
<p>Here’s a little-known trick: Derived values don't need to live in state. 🚀 If your data can be computed from existing states or props, calculate it directly during render.</p>
<p>For example, formatting a date can be done on the fly without additional hooks:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> formattedDate = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>(date).toLocaleDateString();
</code></pre>
<p>The code <code>const formattedDate = new Date(date).toLocaleDateString();</code> derives a formatted date string from a given <code>date</code> input without storing it in the component's state. By creating <code>formattedDate</code> as a constant, it calculates the value on the fly each time it's called, reflecting the current state of <code>date</code>.</p>
<p>This approach avoids unnecessary state management, simplifies rendering logic, and keeps the component efficient, as derived values are recalculated only when the underlying data changes. Thus, it promotes a clean, functional style of programming in React</p>
<p>This keeps your components clean and avoids unnecessary state updates.</p>
<h2 id="heading-compute-values-without-effects">Compute Values Without Effects</h2>
<p>Stop using useEffect for simple computations! 🛑 If your value can be calculated directly from state or props and doesn’t involve side effects, do it during render. For expensive computations, wrap them in useMemo to optimize performance:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> expensiveValue = useMemo(<span class="hljs-function">() =&gt;</span> computeExpensiveValue(data), [data]);This reduces the complexity <span class="hljs-keyword">of</span> your code and keeps your components focused.
</code></pre>
<p>The code <code>const expensiveValue = useMemo(() =&gt; computeExpensiveValue(data), [data]);</code> uses the <code>useMemo</code> hook to compute a value (<code>expensiveValue</code>) based on the <code>data</code> input without triggering side effects.</p>
<p>It memoizes the result of <code>computeExpensiveValue(data)</code>, recalculating it only when <code>data</code> changes. This approach prevents unnecessary recalculations on every render, enhancing performance for expensive computations.</p>
<p>By relying on <code>useMemo</code>, the component efficiently derives the value based on its current props or state, keeping the rendering process efficient and focused on the latest data.</p>
<h2 id="heading-keys-should-be-unique">Keys Should Be Unique</h2>
<p>Guilty as charged: I’ve used array indexes as keys in lists before. 😅 But did you know this can lead to bugs? React relies on unique keys to identify items, and using non-unique values can mess things up.</p>
<p>Generate unique IDs using crypto.randomUUID() but make sure to do it only when your state updates, not on every render. For objects, consider adding an id property:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> itemWithId = items.map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> ({ ...item, <span class="hljs-attr">id</span>: generateUniqueId() }));
</code></pre>
<p>The code <code>const itemWithId =</code> <a target="_blank" href="http://items.map"><code>items.map</code></a><code>(item =&gt; ({ ...item, id: generateUniqueId() }));</code> creates a new array, itemWithId, where each item in the items array is augmented with a unique id.</p>
<p>The spread operator (<code>...item</code>) copies the properties of each item, while <code>generateUniqueId()</code> generates a new, unique identifier. This ensures that each item has a distinct key, which is crucial for React components when rendering lists.</p>
<p>Unique keys help React efficiently manage updates, identify changes, and optimize rendering performance by distinguishing between different list items.</p>
<h2 id="heading-dont-leave-out-dependencies">Don't Leave Out Dependencies</h2>
<p>One of React’s cruel quirks: Forgetting dependencies in <code>useEffect</code> can lead to stale closures. 😱 For example, if you <code>useEffect</code> doesn’t include the dependencies it needs, it might not update as expected.</p>
<p>Always double-check your dependency arrays:</p>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {<span class="hljs-comment">// Effect logic}, [dependency]);</span>
</code></pre>
<p>The code <code>useEffect(() =&gt; { /* Effect logic */ }, [dependency]);</code> defines a side effect in a React component that runs when the specified <code>dependency</code> changes. It's essential to include all relevant dependencies in the dependency array to ensure that the effect behaves correctly.</p>
<p>Omitting dependencies can lead to stale or incorrect values being used in the effect, as React may not re-run it when needed. Including all dependencies helps maintain synchronization between the component's state and the effect, ensuring predictable behaviour and preventing potential bugs related to missed updates.</p>
<p>If your UI isn’t updating correctly, this is often the culprit.</p>
<h2 id="heading-use-useeffect-last">Use <code>useEffect</code> Last</h2>
<p>Here’s a pro tip: Don’t rush to use <code>useEffect</code>. 🙅‍♂️ It’s powerful but can lead to messy code if overused. React frameworks provide solutions to manage side effects more elegantly. For data fetching, consider libraries like TanStack Query or SWR that handle requests and caching efficiently, leading to a better user experience.</p>
<p>Alternative strategies:</p>
<ul>
<li><p>Derive values directly.</p>
</li>
<li><p>Respond to events with handlers.</p>
</li>
</ul>
<p>Fetch data on the server or with dedicated libraries.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>React is a robust library, but knowing how to use it effectively can make all the difference. These lessons are just the beginning.</p>
<p>Having an in-depth idea about in and outs of any technology helps you during development and optimization.</p>
<p>React Js is the perfect library for modern development it has everything to offer for development and optimization</p>
<p>Thanks for reading, and happy coding! 🎉</p>
<ul>
<li><p>Follow Me on X: <a target="_blank" href="https://x.com/prankurpandeyy">Prankur's Twitter</a></p>
</li>
<li><p>Follow me on LinkedIn: <a target="_blank" href="https://linkedin.com/in/prankurpandeyy">Prankur's Linkedin</a></p>
</li>
<li><p>Look at my Portfolio here: <a target="_blank" href="https://prankurpandeyy.netlify.app">Prankur's Portfolio</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Successful Low-Code Apps: The Power of Knowledge Transfer in Development Teams ]]>
                </title>
                <description>
                    <![CDATA[ Low-code models, such as Microsoft's Power Platform, make it simple for anyone to start creating applications. The barriers to entry are relatively low, as users need only a work or school email to ge ]]>
                </description>
                <link>https://www.freecodecamp.org/news/low-code-knowledge-transfer/</link>
                <guid isPermaLink="false">66d87a73191c724ea0c7ef03</guid>
                
                    <category>
                        <![CDATA[ Low Code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ teamwork ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Collaboration ]]>
                    </category>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Brandon Wozniewicz ]]>
                </dc:creator>
                <pubDate>Wed, 04 Sep 2024 15:19:15 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724883531478/4fa7979a-e61a-4268-94dc-a48dfcf17b4b.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Low-code models, such as Microsoft's Power Platform, make it simple for anyone to start creating applications. The barriers to entry are relatively low, as users need only a work or school email to get started. Developers can also quickly release new applications into the wild.</p>
<p>But as this happens, questions arise, such as who supports these applications? And who will make the updates if there is a feature request or bug?</p>
<p>Many low-code applications are often created by a single developer, inherently leading to a single point of failure.</p>
<p>And don't let the advertised simplicity of low-code trick you into thinking anyone can edit the app, fix any issues, and add new features. Low code can still contain complexity, and complex solutions can quickly become a problem for organizations and teams that leverage dozens, if not hundreds, of other low- or non-low-code dependencies.</p>
<p>This doesn't mean that organizations should strictly restrict who can create these applications. Doing so would contradict the very purpose of low code. It's a model that empowers stakeholders themselves to rapidly prototype ideas and develop low-cost solutions to problems that, in traditional development, might cost millions of dollars.</p>
<p>In this low-code world, both organizations and developers need a plan. Developers, specifically, should have a plan to transfer knowledge of their products, whether working in a team or independently.</p>
<h2 id="heading-how-to-simplify-complexity">How to Simplify Complexity</h2>
<p>Our relatively small team has created numerous low-code solutions, primarily leveraging Microsoft's suite of products. Some of these solutions are simple low-code canvas apps, while others contain hundreds of dependencies that are anything but low-code.</p>
<p>We've learned, sometimes the hard way, the importance of ensuring maintainability in our development. This means supporting the applications we build and enabling existing and new team members to support them in the future.</p>
<p>Initially, we found ourselves drawn to the premise of being able to create products that solve problems quickly. Before we knew it, we had our own problem: how do we support the array of these products, ensuring that not just us but new team members could do so as well?</p>
<h3 id="heading-slow-down-to-speed-up">Slow Down to Speed Up</h3>
<p>This might sound contrary to the low-code paradigm, but taking frequent pauses to consider the long-term impacts of your decisions is critical to ensuring the tools you build today can be supported tomorrow.</p>
<p>This does not mean reverting back to the speeds of traditional software development, but you should not consider building low-code products as a race to the finish line.</p>
<h3 id="heading-pair-programming">Pair Programming</h3>
<p>Incorporating traditional software development practices can significantly benefit the low-code movement. Even if your applications involve little to no conventional code, concepts like pair programming can be effectively applied when building low-code products.</p>
<p>Take, for example, the process of building a Power App. Traditionally, only one person could edit an app at a time. Although that limitation has changed—multiple people can now edit an app simultaneously—defining a collaborative process remains crucial.</p>
<p>Our team often employs a primary "driver" approach, where one member leads the development while another observes, providing real-time feedback and suggestions.</p>
<p>This method keeps everyone engaged and helps mitigate the effects of tunnel vision on the product. And this collaborative approach is especially valuable for more complex aspects of the application.</p>
<p>For more straightforward tasks, we often work in parallel but stay closely connected via Teams or Zoom, ready to coordinate and ensure each different component is part of a cohesive whole.</p>
<h3 id="heading-applicationcode-reviews">Application/Code Reviews</h3>
<p>Low code doesn't mean no code. It is challenging to create robust applications with drag-and-drop alone. Even something like Power Apps has its own language called Power FX.</p>
<p>Schedule time each week to walk through or review others' applications to become familiar with their creations. Look for places where things can be improved, and be ready to accept feedback on your creations, too.</p>
<p>If you're using traditional code in your project, some of this can be accomplished with PRs. For purely low-code implementations, keep a document of changes and have a sign-off process to ensure other team members can access new changes.</p>
<p>For example, imagine adding a new screen to a Canvas app, allowing users to update personal settings. That change should be documented as unreviewed until at least one other team member has reviewed and signed off on this new feature.</p>
<h3 id="heading-get-other-team-members-involved">Get Other Team Members Involved</h3>
<p>If you're on a team, each product should involve at least two people to avoid single points of failure. Ensure each product has a primary and secondary developer or product owner. For larger teams, allow that secondary role to rotate, ensuring each member is more intimately involved with the team's products.</p>
<p>One way to get others involved and up to speed is to have other team members add new features or fix bugs in existing products under the guidance of the primary or lead developer. This knowledge transfer will help cultivate ownership in the various products your team supports, leading to higher engagement and motivation.</p>
<p>Additionally, as the workload is distributed more evenly across the team, bottlenecks are reduced, allowing for more expeditious handling of fixing bugs and enhancing products.</p>
<h2 id="heading-when-a-hands-on-approach-isnt-possible">When a Hands-On-Approach isn't Possible...</h2>
<p>Much of what I describe above is an attempt to get others involved with projects. The more we touch these things, the better we will understand them.</p>
<p>Inevitably, however, when this hands-on experience isn't possible, it is essential to have practices that can mitigate the effects of isolated development—that is, a development done by one or just a few people.</p>
<p>The two most important things we can do are create and maintain comprehensive documentation about our products and use standard practices as much as possible. We'll talk about documentation first.</p>
<h3 id="heading-document-document-document">Document, Document, Document</h3>
<p>As you've probably experienced, the low-code movement allows applications to be created quickly. The more applications exist, the fewer touchpoints we have with older ones. While those touchpoints are critical to the knowledge transfer process, relying on them alone isn't enough.</p>
<p>Whether you're on a team or a solo developer, creating documentation that describes each aspect of your products is critical. For small projects, this may be a simple text document. For larger projects, you could utilize a SharePoint site. Of course, as products become even more complex, the various dependencies will likely have their own documentation (for example, Git repositories).</p>
<p>Here is an example of how you might document a product you are building:</p>
<p>Let's say you have an application that allows users to reserve a conference room for meetings. That application consists of a user interface (such as a Canvas app) and custom code that creates a follow-up reminder for the person who reserved the meeting a day before. This reminder could send an email to remind the user about the meeting, and if the meeting is no longer occurring, encourage them to cancel the reservation. Finally, this product could also have a reporting element, where administrators can see conference room utilization over time to better understand demand.</p>
<p>Here is how you might document this project:</p>
<ol>
<li><p>Establish a single source of truth about this project, such as a SharePoint page.</p>
</li>
<li><p>This page briefly describes the project, the product owners, and the lead developers.</p>
</li>
<li><p>The page would also briefly describe this project's components (Canvas app, custom code, and reporting dashboard).</p>
</li>
<li><p>Finally, you would include documentation on any easy-to-overlook aspects or non-standard project implementations (more on standardization later).</p>
</li>
</ol>
<p>The SharePoint page handles the high-level overview of the project and gets you pointed in the right direction. Regarding the individual components, the Canvas app will include comments and notes in the version history, and your custom code will leverage Git and often include a detailed readme.</p>
<p>Documentation can be challenging, but it is critical. While documentation should be comprehensive, it should complement the hands-on knowledge transfer techniques described above.</p>
<h3 id="heading-standardize-as-much-as-possible">Standardize as Much as Possible</h3>
<p>Whether it is low-code or traditional development, it is important to have standard practices. This is even more important when talking about low code because of the speed at which things can be developed and potentially get out of control.</p>
<p>From project planning, design, development, and testing to cross training team members, make time to create standard practices for each phase.</p>
<p>Standardization shouldn't be considered a way to eliminate the need for cross-training and documentation but rather a way to complement those stages and reduce the time needed in those areas.</p>
<p>If you can approach a problem the same way every time, you can spend time discussing those non-standard and easy-to-forget parts of what you're building.</p>
<p>Here are some questions to get you started:</p>
<ol>
<li><p>What big-picture steps will each application require? Who will be involved in those steps?</p>
</li>
<li><p>What tools will you use? (for example, Power Apps, Appian, Pega)</p>
</li>
<li><p>Can you support traditional development? If so, how will that look?</p>
</li>
<li><p>What is your philosophical approach to development? For example, should you design the user interface or business logic first? What database will you use? (for example, SharePoint or Dataverse)</p>
</li>
<li><p>What conventions will you use in your code? (for example, naming conventions for screens and variables)</p>
</li>
<li><p>What does this knowledge transfer or cross-training process look like? Do you have dedicated times each week to review each other's work?</p>
</li>
</ol>
<p>Of course, this list goes on. The more you learn, the more you'll realize what needs to be discussed. Get started by creating a Standard Operating Procedure (SOP), and be prepared to edit it early and often.</p>
<h2 id="heading-what-if-i-am-a-solo-developer">What if I am a Solo Developer?</h2>
<p>If you're a solo developer, it may be easy to think that the recommendations above don't apply. But this couldn't be further from the truth. Creating and maintaining a knowledge-transfer framework is even more critical as a solo developer. While co-developing and pair programming are not directly applicable, the concepts still apply.</p>
<p>For example, take time to meet other developers and ask for feedback. At a minimum, it will be an excellent way to meet other people doing the same thing. And, of course, with AI taking a front row in programming, you can always leverage AI to help you learn new techniques and optimize the things you are building.</p>
<p>Finally, documentation and standard practices are just as necessary for the individual developer. First, if you ever work with others, you'll have a reference for your work. Second, these things will act as an external reminder of how you intend to solve development-related problems in the future.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>While low-code platforms offer incredible speed and flexibility, they can also introduce challenges when it comes to maintenance. Rapid development, if not managed carefully, can lead to issues that undermine the long-term success of your applications.</p>
<p>But by intentionally slowing down and establishing a clear plan for knowledge transfer, you can safeguard the future of your critical products. This approach ensures that applications remain supported and sustainable, both now and for years to come.</p>
<p>Stay curious.</p>
<p>Found this helpful? I write about practical automation, productivity systems, and building smarter workflows — without the jargon. Visit me at <a href="http://brandonwoz.com">brandonwoz.com</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Effectively Manage Unique Identifiers at Scale: From GUIDs to Snowflake IDs and Other Modern Solutions ]]>
                </title>
                <description>
                    <![CDATA[ What Are Unique Identifiers? 🪪 Unique identifiers (UIDs) are crucial components in software engineering and data management. They serve as distinct references for entities within a system and ensure that each item – whether a database record, a user... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-effectively-manage-unique-identifiers-at-scale/</link>
                <guid isPermaLink="false">66c4dea5fd5e7dd1b40d4a81</guid>
                
                    <category>
                        <![CDATA[ scalability ]]>
                    </category>
                
                    <category>
                        <![CDATA[ design patterns ]]>
                    </category>
                
                    <category>
                        <![CDATA[ unique identifier ]]>
                    </category>
                
                    <category>
                        <![CDATA[ guid ]]>
                    </category>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Gor Grigoryan ]]>
                </dc:creator>
                <pubDate>Tue, 20 Aug 2024 18:21:25 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1724012658962/2e754dc4-248a-4a2b-8819-993514474a22.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="heading-what-are-unique-identifiers">What Are Unique Identifiers? 🪪</h2>
<p>Unique identifiers (UIDs) are crucial components in software engineering and data management. They serve as distinct references for entities within a system and ensure that each item – whether a database record, a user, or a file – can be uniquely identified and accessed.</p>
<p>UIDs are critical for maintaining data, enabling efficient search and retrieval, and supporting large-scale operations in distributed systems. As data volumes and system complexities grow, the need for scalable UID solutions becomes increasingly important.</p>
<p>In this article, you'll learn all about the history of unique identifiers, as well as how some modern solutions work.</p>
<h2 id="heading-table-of-contents">Table of Contents:</h2>
<ul>
<li><p><a class="post-section-overview" href="#introduction-to-unique-identifiers-">Introduction to Unique Identifiers 🪪</a></p>
<ul>
<li><p><a class="post-section-overview" href="#the-historical-context-of-identifiers">The Historical Context of Identifiers</a></p>
</li>
<li><p><a class="post-section-overview" href="#government-management-of-unique-identifiers">Government Management of Unique Identifiers</a></p>
</li>
<li><p><a class="post-section-overview" href="#structure-of-social-security-numbers">Structure of Social Security Numbers</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#scalability-in-government-systems">Scalability in Government Systems</a></p>
<ul>
<li><p><a class="post-section-overview" href="#tech-companies-and-their-scale">Tech Companies and Their Scale</a></p>
</li>
<li><p><a class="post-section-overview" href="#meta-facebook-">Meta (Facebook)</a></p>
</li>
<li><p><a class="post-section-overview" href="#x-twitter-">X (Twitter)</a></p>
</li>
<li><p><a class="post-section-overview" href="#telegram">Telegram</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#the-role-of-auto-increment-ids-and-their-scalability-issues">The Role of Auto-increment IDs and Their Scalability Issues</a></p>
</li>
<li><p><a class="post-section-overview" href="#sequence-numbers-and-their-advantages-over-auto-increment-ids">Sequence Numbers and Their Advantages Over Auto-increment IDs</a></p>
</li>
<li><p><a class="post-section-overview" href="#uuids-overview-and-usage">UUIDs: Overview and Usage</a></p>
<ul>
<li><p><a class="post-section-overview" href="#what-s-so-great-about-uuids">What's so great about UUIDs?</a></p>
</li>
<li><p><a class="post-section-overview" href="#uuid-version-1">UUID Version 1</a></p>
</li>
<li><p><a class="post-section-overview" href="#uuid-version-4">UUID Version 4</a></p>
</li>
<li><p><a class="post-section-overview" href="#uuid-version-5">UUID Version 5</a></p>
</li>
<li><p><a class="post-section-overview" href="#uuid-version-7">UUID Version 7</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-uuid-version-2-3-and-6">UUID Version 2, 3, and 6</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#snowflake-id">Snowflake ID</a></p>
<ul>
<li><p><a class="post-section-overview" href="#the-problem-stated-by-twitter-">"The Problem" stated by twitter:</a></p>
</li>
<li><p><a class="post-section-overview" href="#finding-tweet-timestamps">Finding Tweet Timestamps</a></p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-the-historical-context-of-identifiers">The Historical Context of Identifiers</h3>
<p>The concept of unique identifiers has enveloped significantly over time, reflecting the growing complexity and scale of human societies and technological systems. To understand why unique identifiers are so important today, let’s look at how we've historically managed identification and how it was developed.</p>
<p>In early human societies, individuals were often identified by a <strong>single name</strong>. This was usually sufficient in small communities where everyone knew each other personally. But as populations grew, it became necessary to distinguish between individuals who shared the same first name. This led to the adoption of <strong>surnames</strong>.</p>
<p>For example, in Armenia 🇦🇲, surnames are used to identify individuals by their family or ancestry. Take the example of a person named Gor. In a small group of up to 50 people, let's say, identifying Gor by his first name alone is easy.</p>
<p>But as the group grows to a larger community of, say, 500 people, additional identifiers become necessary. Gor will be identified as Gor Grigoryan, indicating that he belongs to the Grigoryan family/ancestry. This surname provides a clearer identification and connects Gor to his family's lineage.</p>
<p>As societies continued to expand and bureaucratic systems became more complex, even surnames proved not enough for uniquely identifying individuals. This was especially true in larger cities and for the administration of government services. The need for more robust identification methods became apparent.</p>
<h3 id="heading-government-management-of-unique-identifiers">Government Management of Unique Identifiers</h3>
<p>The introduction of passports in the early 20th century marked a significant step in this direction. Passports included unique personal identifiers, such as passport numbers, to distinguish between individuals clearly. These unique IDs ensured that each person could be accurately identified, regardless of name similarities or other ambiguities.</p>
<p>Several countries pioneered the use of unique personal identification numbers to address this need:</p>
<ul>
<li><p><strong>Germany</strong> 🇩🇪: In the 19th century, Germany implemented a system for tracking individuals for social welfare and military conscription purposes.</p>
</li>
<li><p><strong>Sweden</strong> 🇸🇪: Sweden began issuing personal identification numbers (Personnummer) in the 1940s, providing each citizen with a unique identifier for use in various administrative processes.</p>
</li>
<li><p><strong>France</strong> 🇫🇷: France introduced the National Identification Number (Numéro de Sécurité Sociale) in the mid-20th century to streamline social security administration and other government services.</p>
</li>
<li><p><strong>United States</strong> 🇺🇸: The USA followed with the introduction of Social Security Numbers (SSNs) in 1936 as part of the Social Security Act. This approach to unique identification has since been adopted worldwide, with countries issuing national identification numbers to their citizens.</p>
</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/image-49.png" alt="image-49" width="600" height="400" loading="lazy"></p>
<p>Information page, Edwin James Tharp’s passport, March 27, 1936, <a target="_blank" href="https://library.csun.edu/SCA/Peek-in-the-Stacks/identities">Robert and Eva Tharp Collection</a>.</p>
<p>As illustrated in the example image, the 1936 UK 🇬🇧 passport included detailed personal information such as eye color, hair color, profession, height, and information about the holder’s spouse and children.</p>
<h3 id="heading-structure-of-social-security-numbers">Structure of Social Security Numbers</h3>
<p>A Social Security Number (SSN) in the United States is a nine-digit number formatted as "AAA-GG-SSSS". Each part of the SSN has historically carried specific information:</p>
<ol>
<li><p><strong>Area Number (AAA)</strong>: Originally, the first three digits, known as the area number, represented the geographical region where the SSN was issued. This regional assignment helped to ensure a systematic distribution of numbers across the country.</p>
</li>
<li><p><strong>Group Number (GG)</strong>: The middle two digits, called the group number, were used to organize the numbers within a given area. The group numbers ranged from 01 to 99 and were issued in a specific order to prevent duplicate numbers within the same area.</p>
</li>
<li><p><strong>Serial Number (SSSS)</strong>: The last four digits are the serial number, which sequentially identifies each individual within a group. This part of the SSN ensures that even if the area and group numbers are the same, the overall SSN remains unique.</p>
</li>
</ol>
<p>The Social Security Administration (SSA) has implemented several measures to ensure that each SSN is unique for the entire USA population (<strong>341.9 million people).</strong></p>
<p>Governments around the world manage unique identifiers primarily for administrative purposes, such as social security, taxation, and national identification. These systems are designed to handle large populations and ensure that every citizen has a unique identifier for official records.</p>
<p>For example, the United States 🇺🇸 Social Security Administration (SSA) manages Social Security Numbers (SSNs) for over 330 million people. Similarly, the Indian 🇮🇳 government has issued Aadhaar numbers, a 12-digit unique identifier, to over <strong>1.3 billion citizens</strong>. These identifiers are crucial for accessing government services, benefits, and other official processes.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/image-52.png" alt="image-52" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://en.wikipedia.org/wiki/Aadhaar">Aadhaar is the world's largest biometric ID system</a> described as "the most sophisticated ID program in the world".</p>
<h2 id="heading-scalability-in-government-systems">Scalability in Government Systems</h2>
<p>While government systems are large, they generally do not face the same scalability challenges as tech companies. Government databases are often centralized, and the rate at which new identifiers are issued is relatively steady and predictable. Also, the frequency of updates and interactions with these identifiers is lower compared to the dynamic environment of tech companies.</p>
<p>Tech companies, especially social media giants, operate on an entirely different scale. These companies manage billions of users and generate vast amounts of data daily. For instance, Meta (formerly Facebook) has over 3 billion monthly active users across its platforms, including Facebook, Instagram, and WhatsApp.</p>
<h3 id="heading-tech-companies-and-their-scale">Tech Companies and Their Scale</h3>
<p>Let's take a few examples:</p>
<h4 id="heading-meta-facebook">Meta (Facebook)</h4>
<ol>
<li><p><strong>User Base</strong>: With over <strong>3 billion monthly active users</strong>, Meta needs a robust system to ensure that each user is uniquely identified.</p>
</li>
<li><p><strong>Posts and Interactions</strong>: Facebook alone sees approximately <strong>350 million new posts daily</strong>. Each of these posts, along with comments, likes, and shares require a unique identifier to manage interactions efficiently.</p>
</li>
<li><p><strong>Messages</strong>: WhatsApp users send around <strong>100 billion messages every day</strong>, each needing a unique identifier to ensure messages are correctly routed and stored.</p>
</li>
<li><p><strong>Unique Data Rows</strong>: With the combination of user profiles, posts, comments, likes, and messages, Meta likely manages over <strong>10+ trillion unique data rows</strong>. (If the global population is approximately 8 billion people, then 10 trillion people would be about <strong>1,250</strong> times the current global population).</p>
</li>
</ol>
<h4 id="heading-x-twitter">X (Twitter)</h4>
<p>Twitter, another social media giant, has about <strong>450 million monthly active users</strong>. On average, users send around <strong>500 million tweets per day</strong>. Each tweet, reply, and retweet needs a unique identifier to maintain the platform's integrity and usability.</p>
<h4 id="heading-telegram">Telegram</h4>
<p>Telegram is known for its high-traffic and robust messaging platform. With over <strong>700 million monthly active users</strong>, Telegram experiences particularly high traffic spikes during events like New Year's Eve, where users send billions of messages within a short timeframe.</p>
<p>On a typical day, Telegram handles over <strong>70 billion messages</strong>. Each message, channel post, and group interaction requires a unique identifier to ensure proper delivery and organization.</p>
<p>The scale at which tech companies operate requires sophisticated and highly scalable unique identifier systems. These systems must handle high concurrency, support distributed architectures, and ensure low latency.</p>
<h2 id="heading-the-role-of-auto-increment-ids-and-their-scalability-issues">The Role of Auto-increment IDs and Their Scalability Issues</h2>
<p>Auto-increment IDs are a common method for generating unique identifiers in relational databases. When a new record is added to a table, the database automatically assigns the next available integer value to the ID field. This method is straightforward and ensures that each record within a table has a unique identifier without requiring any manual intervention.</p>
<p>Consider a table for storing user information in a relational database. When the first user is added, they might be assigned an ID of 1. The second user would receive an ID of 2, and so on.</p>
<p>While auto-increment IDs are simple and effective for small-scale applications, they face significant challenges in larger, distributed systems.</p>
<ol>
<li><p><strong>Concurrency Issues</strong>: In high-traffic applications, multiple transactions might attempt to insert records simultaneously. Ensuring that each transaction receives a unique auto-increment ID can lead to performance bottlenecks and require complex locking mechanisms.</p>
</li>
<li><p><strong>Distributed Systems</strong>: In distributed databases, where data is spread across multiple servers, maintaining a global sequence for auto-increment IDs becomes problematic. Each server would need to coordinate with others to avoid generating duplicate IDs, which can significantly impact performance and reliability.</p>
</li>
<li><p><strong>Single Point of Failure</strong>: Relying on a central authority to generate auto-increment IDs introduces a single point of failure. If the server responsible for assigning IDs goes down, the entire system might be unable to add new records.</p>
</li>
<li><p><strong>Predictability</strong>: Auto-increment IDs are predictable. If someone knows the ID of one record, they can infer the IDs of subsequent records. This predictability can be a security concern in certain applications, such as those involving financial transactions or sensitive user data.</p>
</li>
</ol>
<pre><code class="lang-sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> Admins (
    <span class="hljs-keyword">Id</span> <span class="hljs-built_in">SERIAL</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    <span class="hljs-keyword">Name</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>
);

<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">Users</span> (
    <span class="hljs-keyword">Id</span> <span class="hljs-built_in">SERIAL</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    <span class="hljs-keyword">Name</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>
);

<span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> Admins (<span class="hljs-keyword">Name</span>)
<span class="hljs-keyword">VALUES</span> (<span class="hljs-string">'GorGrigoryan'</span>),
       (<span class="hljs-string">'GorGrigoryan2'</span>);

<span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> Admins;


<span class="hljs-comment">-- +----+---------------+</span>
<span class="hljs-comment">-- | Id | Name          |</span>
<span class="hljs-comment">-- +----+---------------+</span>
<span class="hljs-comment">-- | 1  | GorGrigoryan  |</span>
<span class="hljs-comment">-- +----+---------------+</span>
<span class="hljs-comment">-- | 2  | GorGrigoryan2 |</span>
<span class="hljs-comment">-- +----+---------------+</span>
</code></pre>
<h2 id="heading-sequence-numbers-and-their-advantages-over-auto-increment-ids">Sequence Numbers and Their Advantages Over Auto-increment IDs</h2>
<p>Sequence numbers are a method of generating unique identifiers by maintaining a counter that is incremented with each new record. Unlike auto-increment IDs, which are typically limited to a single database instance, sequence numbers can be designed to work across distributed systems, addressing some of the scalability and concurrency issues associated with auto-increment IDs.</p>
<p>How sequence numbers work:</p>
<ol>
<li><p><strong>Centralized Sequence Generators</strong>: A central service or database table generates and manages the sequence numbers. Each request for a new identifier increments the counter and returns the next value.</p>
</li>
<li><p><strong>Distributed Sequence Generators</strong>: In a distributed environment, sequence numbers can be generated by dividing the range of possible values among different nodes or using more complex algorithms to ensure uniqueness without central coordination.</p>
</li>
</ol>
<p>Consider a distributed database system with multiple nodes, each responsible for generating unique sequence numbers. The system might allocate ranges of sequence numbers to each node, ensuring that they can generate identifiers independently:</p>
<ul>
<li><p><strong>Node 1</strong>: Allocated sequence numbers 1,000,000 to 1,999,999</p>
</li>
<li><p><strong>Node 2</strong>: Allocated sequence numbers 2,000,000 to 2,999,999</p>
</li>
<li><p><strong>Node 3</strong>: Allocated sequence numbers 3,000,000 to 3,999,999</p>
</li>
</ul>
<p>Each node can now generate up to one million unique identifiers without needing to communicate with a central server. This approach improves scalability and performance, particularly in environments with high write loads.</p>
<pre><code class="lang-sql"><span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">SEQUENCE</span> UserIdentifier
<span class="hljs-keyword">INCREMENT</span> <span class="hljs-number">1</span>
<span class="hljs-keyword">START</span> <span class="hljs-number">1</span>;

<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> Admins (
    <span class="hljs-keyword">Id</span> <span class="hljs-built_in">INT</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    <span class="hljs-keyword">Name</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>
);

<span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> <span class="hljs-keyword">Users</span> (
    <span class="hljs-keyword">Id</span> <span class="hljs-built_in">INT</span> PRIMARY <span class="hljs-keyword">KEY</span>,
    <span class="hljs-keyword">Name</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">255</span>) <span class="hljs-keyword">NOT</span> <span class="hljs-literal">NULL</span>
);


<span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> Admins (<span class="hljs-keyword">Id</span>, <span class="hljs-keyword">Name</span>)
<span class="hljs-keyword">VALUES</span>(<span class="hljs-keyword">nextval</span>(<span class="hljs-string">'UserIdentifier'</span>), <span class="hljs-string">'GorGrigoryan'</span>),
(<span class="hljs-keyword">nextval</span>(<span class="hljs-string">'UserIdentifier'</span>), <span class="hljs-string">'GorGrigoryan2'</span>);

<span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> <span class="hljs-keyword">Users</span> (<span class="hljs-keyword">Id</span>, <span class="hljs-keyword">Name</span>)
<span class="hljs-keyword">VALUES</span>(<span class="hljs-keyword">nextval</span>(<span class="hljs-string">'UserIdentifier'</span>), <span class="hljs-string">'UserGorGrigoryan'</span>),
(<span class="hljs-keyword">nextval</span>(<span class="hljs-string">'UserIdentifier'</span>), <span class="hljs-string">'UserGorGrigoryan2'</span>);


<span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> Admins;

<span class="hljs-comment">-- +----+---------------+</span>
<span class="hljs-comment">-- | Id | Name          |</span>
<span class="hljs-comment">-- +----+---------------+</span>
<span class="hljs-comment">-- | 1  | GorGrigoryan  |</span>
<span class="hljs-comment">-- +----+---------------+</span>
<span class="hljs-comment">-- | 2  | GorGrigoryan2 |</span>
<span class="hljs-comment">-- +----+---------------+</span>

<span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> <span class="hljs-keyword">Users</span>;

<span class="hljs-comment">-- +----+---------------+</span>
<span class="hljs-comment">-- | Id | Name          |</span>
<span class="hljs-comment">-- +----+---------------+</span>
<span class="hljs-comment">-- | 3  | GorGrigoryan  |</span>
<span class="hljs-comment">-- +----+---------------+</span>
<span class="hljs-comment">-- | 4  | GorGrigoryan2 |</span>
<span class="hljs-comment">-- +----+---------------+</span>
</code></pre>
<p>Another advantage of using sequence numbers is that you can obtain the ID of the entity before it is inserted into the database.</p>
<p>In the case of auto-increment IDs, this assignment is typically handled by the database upon insertion, which can limit flexibility. With sequence numbers, you can easily generate the ID on the application side, which can be an easy task when using some ORMs e.g the EF Core ORM in C#</p>
<p>Check out sequence numbers on the SQL server <a target="_blank" href="https://learn.microsoft.com/en-us/sql/relational-databases/sequence-numbers/sequence-numbers?view=sql-server-ver16">here</a>.</p>
<h2 id="heading-uuids-overview-and-usage">UUIDs: Overview and Usage</h2>
<p>GUIDs (Globally Unique Identifiers), also known as UUIDs (Universally Unique Identifiers), are 128-bit identifiers designed to be globally unique. A typical UUID is displayed in a 32-character hexadecimal string, divided into five groups separated by hyphens. For example: <code>126e3456-e89b-12d3-a456-426614174000</code>.</p>
<h3 id="heading-whats-so-great-about-uuids">What's so great about UUIDs?</h3>
<p>One of the standout features of GUIDs is their huge capacity for uniqueness. With a 128-bit structure, the total number of possible GUIDs is very large: Specifically, there are <code>340,282,366,920,938,463,463,374,607,431,770,000,000</code> GUIDs available. To put that into perspective, let's compare it with something tangible.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/image-94.png" alt="image-94" width="600" height="400" loading="lazy"></p>
<p>Did you know that scientists have attempted to calculate the number of grains of sand on Earth? Science writer David Blatner, in his book <a target="_blank" href="https://www.amazon.com/Spectrums-Mind-boggling-Universe-Infinitesimal-Infinity/dp/1620405202">Spectrums</a>, mentions that a group of researchers at the University of Hawaii tried to estimate this number. They determined that Earth has roughly (and we are speaking very roughly) 7.5 x 10<sup>18</sup> grains of sand, or seven quintillion, five hundred quadrillion grains. For more, consider reading the article titled: "<a target="_blank" href="https://www.npr.org/sections/krulwich/2012/09/17/161096233/which-is-greater-the-number-of-sand-grains-on-earth-or-stars-in-the-sky"><strong>Which Is Greater, The Number Of Sand Grains On Earth Or Stars In The Sky?</strong></a><strong>"</strong></p>
<p>Now, to compare those numbers:</p>
<pre><code class="lang-sql">| GUIDs available | 340,282,366,920,938,463,463,374,607,431,770,000,000
| Sand grains     | 75,000,000,000,000,000,000
</code></pre>
<p>If you decided to create an application to track every grain of sand on Earth and assign each a unique identifier, you could easily do that using GUIDs. The fun part is that you could actually repeat this process <code>4,537,098,225,612,512,846</code> times over without running out of unique GUIDs! 🤯</p>
<h3 id="heading-uuid-version-1">UUID Version 1</h3>
<p>UUID Version 1 generates unique identifiers based on the current timestamp, clock sequence, and node identifier (typically the MAC address of the machine generating the UUID).</p>
<p>According to <a target="_blank" href="https://datatracker.ietf.org/doc/html/rfc4122">RFC 4122</a>, the timestamp is the number of nanoseconds since October 15, 1582, at midnight UTC. Most computers do not have a clock that ticks fast enough to measure time in nanoseconds. Instead, a random number is often used to fill in timestamp digits beyond the computer's measurement accuracy.</p>
<p>When multiple version-1 UUIDs are generated in a single API call, the random portion may be incremented rather than regenerated for each UUID. This ensures uniqueness and is faster to generate.</p>
<p>UUID v1 also has the mac address attached to it. By including a MAC address in the UUID, you can be sure that two different computers will never generate the same UUID. Because MAC addresses are globally unique, but also note that version-1 UUIDs can be traced back to the computer that generated them.</p>
<p>This ensures that the UUID is unique across both time and space. It is suitable when the <strong>generation time and machine uniqueness</strong> are important. It is often used in systems where the timestamp of creation is relevant or needed.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/image-95.png" alt="image-95" width="600" height="400" loading="lazy"></p>
<p>(Image from <a target="_blank" href="https://datatracker.ietf.org/doc/html/rfc4122">here</a>)</p>
<h3 id="heading-uuid-version-4">UUID Version 4</h3>
<p>UUID Version 4 generates identifiers using random or pseudo-random numbers. This method ensures a high probability of uniqueness due to the vast number of possible GUIDs. This is the most common UUID version.</p>
<p>There are 2 main variants of UUID:</p>
<ul>
<li><p>Variant 1: <a target="_blank" href="https://minecraft.fandom.com/wiki/Universally_unique_identifier">Minecraft UUID</a>, also called Timestamp-first UUIDs</p>
</li>
<li><p>Variant 2:  "GUID"</p>
</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/image-96.png" alt="image-96" width="600" height="400" loading="lazy"></p>
<p>(<a target="_blank" href="https://www.uuidtools.com/minecraft">Image from here</a>)</p>
<p>GUID is entirely random, making it simple to generate and ensuring that each identifier is unique with a very high probability. The unique identifiers are made up of 128 bits. They are written as 32 characters using numbers (0-9) and letters (A-F). The characters are grouped in a specific format: 8-4-4-4-12, separated by hyphens, like this: <code>{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}</code>.</p>
<p>The great thing about GUIDs is that you don’t need a central system to create them. Anyone can generate a GUID using an algorithm, and it will still be unique across different systems and applications. They are designed to be used nearly everywhere a unique identifier is needed. Here are some usage examples:</p>
<ul>
<li><p>Windows: Uses GUIDs to generate unique product keys</p>
</li>
<li><p>Microsoft SQL Server: Uses GUIDs as primary keys to ensure global uniqueness across distributed databases</p>
</li>
<li><p>AWS: Uses GUIDs for uniquely identifying resources in their cloud infrastructure, such as EC2 instances and S3 objects</p>
</li>
<li><p>eBay: Uses GUIDs to identify listings, transactions, and users</p>
</li>
</ul>
<h3 id="heading-uuid-version-5">UUID Version 5</h3>
<p>UUID Version 5 generates unique identifiers based on a <strong>namespace</strong> identifier and a <strong>name</strong>. The namespace and name are combined and hashed using SHA-1 to produce the UUID. This ensures that the same namespace and name combination will always produce the same UUID. In UUID, the namespace must be a UUID, and the name can be anything.</p>
<p>UUID V5 is useful for generating consistent unique identifiers for the same input data across different systems and contexts. Let's say we want to generate a user id based on their username. Here’s how you can achieve this in C#:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/image-97.png" alt="image-97" width="600" height="400" loading="lazy"></p>
<p>Here the UUID Version 5 solves several important problems, particularly when you need a consistent and unique identifier based on a given input.</p>
<p>For instance, consider a scenario where you need a user ID to make an API call (or anything else), but in your code, you only have the username accessible. How would the problem be solved if we were using UUID Version 4 (GUIDs)? Most likely, it would work something like this:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">/* When using GUID (UUID v4) */</span>

<span class="hljs-keyword">var</span> userName = <span class="hljs-string">"bob"</span>; <span class="hljs-comment">// Lets assume we only have username</span>
<span class="hljs-comment">// API call or DB call to get the user id using name</span>
<span class="hljs-keyword">var</span> userId = <span class="hljs-keyword">await</span> userService.GetUserIdAsync(userName);

<span class="hljs-keyword">await</span> userService.ChangeUserNameAsync(userId, <span class="hljs-string">"bob-2"</span>);
</code></pre>
<p>By using UUID Version 5 with a shared namespace across all your projects, you can easily generate the user ID from the username without making any additional API calls. So the same code would look like this:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">/* When using UUID v5 */</span>

<span class="hljs-comment">// From some shared code</span>
<span class="hljs-keyword">var</span> userNamespace = SharedConstants.UserNamespace;

<span class="hljs-keyword">var</span> userName = <span class="hljs-string">"bob"</span>; <span class="hljs-comment">// Lets assume we only have username</span>

<span class="hljs-comment">//Generate the user id in place, without additional call</span>
<span class="hljs-keyword">var</span> userId = Uuid.NewNameBased(userNamespace, userName);

<span class="hljs-keyword">await</span> userService.ChangeUserNameAsync(userId, <span class="hljs-string">"bob-2"</span>);
</code></pre>
<p>This approach eliminates the need for redundant API calls. In a distributed system, making an API call to fetch a user ID every time you need it can be inefficient and slow. With UUID Version 5, you can locally generate the user ID from the username (or any other input), reducing the need for network requests and significantly improving the efficiency of your application.</p>
<p>What kind of problem have we solved with UUID v5? Let's say you need a user ID to make an API call but in your code, you have only a username, if you have the namespace shared across all your projects. Then you can easily get the user id using a username, without making any API call. That's because UUID v5 always reproduces the same UUID for the same input.</p>
<p>Also, UUID Version 5 ensures uniqueness and consistency across different systems. When integrating multiple systems or microservices, it can be challenging to keep user IDs consistent across various services. By using the same namespace and the same input (such as a username), UUID Version 5 guarantees that the generated IDs are unique and consistent across all systems, facilitating smoother integration and data consistency.</p>
<h3 id="heading-uuid-version-7">UUID Version 7</h3>
<p>GUID Version 7 is a proposed new version that aims to combine the strengths of both timestamp-based and random-based GUIDs.</p>
<h4 id="heading-problems-with-uuid-v4-guid"><strong>Problems with UUID v4 (GUID)</strong></h4>
<p>UUID Version 4 generates non-time-ordered values, meaning the identifiers created are not sequential. Since these values are randomly generated, they won't be clustered together in a database index. Instead, inserts will occur at random locations, which can negatively impact the performance of common index data structures, such as B-trees and their variants.</p>
<p>In a scenario where your product requires <em>frequent access to recent data</em>, non-sequential identifiers create a significant challenge.</p>
<p>With UUID Version 4, the most recent data will be inserted randomly throughout the index, <em>lacking clustering</em>. As a result, retrieving the most recent data from a large dataset requires traversing numerous database index pages.</p>
<p>In contrast, using sequential identifiers ensures that the latest data is logically arranged at the right-most part of the index, making it much more cache-friendly. This organization allows for faster and more efficient retrieval of recent data, as it minimizes the number of index pages that need to be accessed which is a lack in UUID v4.</p>
<h4 id="heading-the-solution-with-uuid-v7"><strong>The solution with UUID v7</strong></h4>
<p>UUID v7 is designed to provide unique and sortable identifiers that are both easy to generate and useful for distributed systems. It uses a combination of timestamps and random data to ensure both uniqueness and temporal order.</p>
<p>The first part of the UUID is a timestamp that provides a chronological component, ensuring that UUIDs generated close together in time are also close together in value. The remaining part is filled with random data, ensuring the uniqueness of each identifier.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/07/image-98.png" alt="image-98" width="600" height="400" loading="lazy"></p>
<p><a target="_blank" href="https://buildkite.com/blog/goodbye-integers-hello-uuids">Buildkite post about migrating to UUID v7</a></p>
<h3 id="heading-uuid-versions-2-3-and-6">UUID Versions 2, 3, and 6</h3>
<p>You may have noticed that our discussion focuses on UUID Versions 1, 4, 5, and 7, and skips over Versions 2, 3, and 6. Here's why:</p>
<ul>
<li><p><strong>UUID Version 2</strong>: This version is rarely used in modern applications. It’s similar to Version 1 but includes additional fields for things like domain information (such as POSIX UID or GID). It was mainly used in legacy systems and is now considered largely obsolete.</p>
</li>
<li><p><strong>UUID Version 3</strong>: This version is based on a name and a namespace, similar to Version 5. The main difference is that Version 3 uses the MD5 hashing algorithm, which is less secure and less efficient than the SHA-1 algorithm used in Version 5. Version 5 is generally preferred because SHA-1 is more robust.</p>
</li>
<li><p><strong>UUID Version 6</strong>: Version 6 is still under draft as a proposed standard. It is meant to provide a time-ordered UUID with better performance for distributed systems, but since it hasn't been fully adopted yet, we focus on Version 7, which offers similar features and has more momentum.</p>
</li>
</ul>
<h2 id="heading-snowflake-id">Snowflake ID</h2>
<p>Snowflake ID is a unique identifier generation system developed by Twitter to address the challenges of generating unique, sequential, and distributed identifiers in a highly scalable and efficient manner.</p>
<p>Unlike GUIDs, which are often non-sequential and can cause performance issues in database indexing, Snowflake IDs are designed to be both time-ordered and globally unique, making them ideal for distributed systems and databases where sequential order is important.</p>
<p>A Snowflake ID is a 64-bit integer composed of several distinct parts:</p>
<ol>
<li><p><strong>Timestamp (41 bits):</strong> The largest portion of the Snowflake ID is the timestamp, which records the number of milliseconds since a custom epoch (often set to the date when the system was first deployed). This ensures that IDs are time-ordered and can be easily sorted based on their creation time.</p>
</li>
<li><p><strong>Datacenter ID (5 bits):</strong> This part of the ID identifies the datacenter where the ID was generated, allowing the system to generate unique IDs across multiple data centers without conflicts.</p>
</li>
<li><p><strong>Machine ID (5 bits):</strong> Similar to the datacenter ID, the machine ID identifies the specific server or machine within the datacenter that generated the ID. This ensures that even within the same data center, IDs remain unique.</p>
</li>
<li><p><strong>Sequence Number (12 bits):</strong> The sequence number is used to differentiate between multiple IDs generated within the same millisecond by the same machine. <em>With 12 bits, up to 4,096 unique IDs can be generated per machine per millisecond.</em></p>
</li>
</ol>
<p>The format was created by Twitter (now X) and is used for the IDs of tweets. It is popularly believed that every snowflake has a unique structure, so they took the name "snowflake ID". The format has been adopted by other companies, including Discord and Instagram. The Mastodon social network uses a modified version.</p>
<p>The format was first announced by X/Twitter in June 2010. Due to implementation challenges, <a target="_blank" href="https://techcrunch.com/2010/10/12/twitter-snowflake/">they waited until later in the year to roll out the update</a>.</p>
<ul>
<li><p>X uses snowflake IDs for posts, direct messages, users, lists, and all other objects available over the API.</p>
</li>
<li><p>Discord also uses snowflakes, with their epoch set to the first second of the year 2015.</p>
</li>
<li><p>Instagram uses a modified version of the format, with 41 bits for a timestamp, and 10 bits for a sequence number.</p>
</li>
<li><p>Mastodon's modified format has 48 bits for a millisecond-level timestamp, as it uses the UNIX epoch. The remaining 16 bits are for sequence data.</p>
</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/08/image-3.png" alt="image-3" width="600" height="400" loading="lazy"></p>
<h3 id="heading-the-problem-stated-by-twitter">"The Problem" stated by Twitter:</h3>
<blockquote>
<p>We currently use MySQL to store most of our online data. In the beginning, the data was in one small database instance which in turn became one large database instance and eventually many large database clusters. For various reasons, the details of which merit a whole blog post, we’re working to replace many of these systems with <a target="_blank" href="http://cassandra.apache.org/">the Cassandra distributed database</a> or horizontally sharded MySQL (using <a target="_blank" href="http://github.com/twitter/gizzard">gizzard</a>).</p>
<p>Unlike MySQL, Cassandra has no built-in way of generating unique ids – nor should it, since at the scale where Cassandra becomes interesting, it would be difficult to provide a one-size-fits-all solution for ids. Same goes for sharded MySQL. We needed something that could generate tens of thousands of ids per second in a highly available manner.</p>
<p>This naturally led us to choose an uncoordinated approach. These ids need to be <em>roughly sortable</em>, meaning that if tweets A and B are posted around the same time, they should have ids in close proximity to one another since this is how we and most Twitter clients sort tweets.</p>
<p>Additionally, these numbers have to fit into 64 bits. We’ve been through the painful process of growing the number of bits used to store tweet ids <a target="_blank" href="http://www.twitpocalypse.com/">before</a>. It’s unsurprisingly hard to do when you have over <a target="_blank" href="http://social.venturebeat.com/2010/04/14/twitter-applications/">100,000 different codebases involved</a>.</p>
</blockquote>
<p>Check out <a target="_blank" href="https://blog.x.com/engineering/en_us/a/2010/announcing-snowflake">here</a> for more information</p>
<h3 id="heading-finding-tweet-timestamps">Finding Tweet Timestamps</h3>
<p>We all know that deleting a tweet isn't truly possible—once it's out there, it's how Twitter is designed. However, Twitter's use of Snowflake IDs adds an interesting twist to this narrative. Snowflake IDs are designed to be unique and time-ordered, which makes them not just identifiers but also a trail that can be tracked.</p>
<p>On May 11, 2019, Derek Willis from Politwoops uncovered a <a target="_blank" href="https://gist.github.com/naumansiddiqui4/ba3398ea85ed0ef1f3af23d47b4dcd42">list of deleted tweet IDs</a>. By using the Snowflake structure, he was able to extract the timestamps from these IDs, and discovered the 107 missing tweets. This finding inspired the creation of TweetedAt, a tool designed to accurately retrieve timestamps from Snowflake IDs and estimate the timing of tweets generated before Snowflake was in use.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/08/image-2.png" alt="image-2" width="600" height="400" loading="lazy"></p>
<p>Check out <a target="_blank" href="https://ws-dl.blogspot.com/2019/08/2019-08-03-tweetedat-finding-tweet.html">here.</a></p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>Unique identifiers play a critical role in software engineering, ensuring data integrity and enabling efficient data management across distributed systems.</p>
<p>From traditional GUIDs to modern solutions like Snowflake IDs, each identifier system offers distinct advantages tailored to specific use cases.</p>
<p>As technology evolves, understanding these systems and their implementations becomes increasingly important for scaling applications effectively. By exploring the various versions and alternatives, we can make informed decisions that best suit our needs in managing data at scale.</p>
<h4 id="heading-cover-image-a-2017-post-celebrating-facebook-reaching-2-billion-usershttpswwwfacebookcomphotofbid10103832396388711ampseta941146602501">Cover image: <a target="_blank" href="https://www.facebook.com/photo/?fbid=10103832396388711&amp;set=a.941146602501">A 2017 post celebrating Facebook reaching 2 billion users</a>.</h4>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Improve Your Digital Security and Privacy – Best Practices for Developers ]]>
                </title>
                <description>
                    <![CDATA[ These days, there are many different types of attacks that can jeopardize your digital security and privacy. So it’s a good idea to stay up-to-date with best practices to keep you safe online.  But it can be hard to understand exactly how to do this.... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-improve-your-digital-security-and-privacy/</link>
                <guid isPermaLink="false">66bae74e18927a8cd306c839</guid>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ privacy ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Security ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Loki Privacy ]]>
                </dc:creator>
                <pubDate>Tue, 18 Jun 2024 12:05:09 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/07/pexels-wdnet-101808.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>These days, there are many different types of attacks that can jeopardize your digital security and privacy. So it’s a good idea to stay up-to-date with best practices to keep you safe online. </p>
<p>But it can be hard to understand exactly how to do this. So I built this tutorial and this <a target="_blank" href="https://loki2100.limesurvey.net/948232?lang=en">personal security/privacy assessment</a>, based on what I've learned building <a target="_blank" href="https://lokiprivacy.com/">Loki Privacy</a>. These resources sum up thousands of hours of practice and research into five impactful (and largely free) steps. </p>
<p>By following these guidelines, you can really increase your digital security and privacy, and perhaps help mitigate a devastating hack of your personal finances or data. </p>
<h2 id="heading-heres-what-well-cover">Here's What We'll Cover:</h2>
<ol>
<li><a class="post-section-overview" href="#heading-1-use-credentials-wisely">Use Credentials Wisely</a></li>
<li><a class="post-section-overview" href="#heading-2-choose-your-browser-wisely">Choose Your Browser Wisely</a></li>
<li><a class="post-section-overview" href="#heading-3-understand-encryption-and-what-it-means">Understand Encryption and What it Means</a></li>
<li><a class="post-section-overview" href="#heading-4-how-you-spend-your-money-digitally-leaves-a-trace">How You Spend Your Money Digitally Leaves a Trace</a></li>
<li><a class="post-section-overview" href="#heading-5-the-devices-you-use-do-matter-for-privacy-and-security">The Devices You Use Do Matter for Privacy and Security</a></li>
</ol>
<h2 id="heading-1-use-credentials-wisely">1: Use Credentials Wisely</h2>
<p>The first step is to properly manage your passwords, and add a layer of security with two-factor authentication.</p>
<p>Nowadays, digital passwords control an immense amount of power and personal information. You might access your bank and/or life savings with them, or critical and personal medical information about yourself. With great power as an Internet user comes great responsibility – and this is true of using modern passwords.</p>
<h3 id="heading-use-a-password-manager">Use a Password Manager</h3>
<p>Ideally, password managers are the best system to manage your credentials. They offer encryption and security to prevent undesired access, and they're able to give two critical properties to good passwords. </p>
<ul>
<li>First, they give you the ability to auto-generate passwords and login with the password manager if chosen. This helps avoid the cardinal sin of personal security on the web: password reuse across multiple services. If one service gets hacked with your password and you're reusing it across the web, hackers will try your login/password across the web, potentially turning one hack into multiple. </li>
<li>Second is that password managers allow you to more easily create longer and more complex passwords.</li>
</ul>
<p>Good options are services like 1Password and BitWarden. You can host your own version of BitWarden on your own server with something like StartOS <a target="_blank" href="https://github.com/Start9Labs/vaultwarden-startos">and the open source implementation of BitWarden, Vaultwarden</a>.</p>
<h3 id="heading-use-a-strong-password">Use a Strong Password</h3>
<p>The number and type of characters in your password can prevent people brute-force attacking you – that is, using machines to guess letter combos. Password strength is very dependent on character length. <a target="_blank" href="https://bitwarden.com/blog/how-long-should-my-password-be/">If you use 14-16 characters</a> or more, it'll take a machine centuries to try to guess the password. But if you use 6 or fewer characters, it's likely your password can be cracked in seconds. </p>
<p>Your password strength can also improve if you add special characters, vary the case from uppercase to lowercase, and add numbers – anything that throws off machines that are going through character combinations by rote, hoping to get lucky. </p>
<h4 id="heading-examples-of-strong-passwords">Examples of strong passwords:</h4>
<ul>
<li>32-strings of random characters, ideally including numbers and special characters</li>
<li>Multiple words strung together with some numbers/special characters to make it easy to work manually</li>
</ul>
<h4 id="heading-examples-of-weak-passwords">Examples of weak passwords:</h4>
<ul>
<li>Commonly used and reused word + number combos, like hello12</li>
<li>Shorter strings like 342yf – the shorter your combination even if seemingly random, the easier to brute force</li>
<li>Passwords you use across multiple services no matter their strength (if one of the passwords gets leaked, that will be attempted with all of your services). </li>
</ul>
<h3 id="heading-setup-two-factor-authentication">Setup Two-Factor Authentication</h3>
<p>You should also add two-factor authentication throughout your devices, and ideally the strongest versions of these. That way, even if one of your passwords gets cracked, it won't matter – because attackers won't have access to a second factor that allows them into your account. </p>
<p>You'll also want to get notifications for failed login attempts. That way you'll know if somebody has cracked your password (and you'll want to remove that password from any online services you currently use.). </p>
<p>Normally, this would be a combination of what's called HOTP and TOTP two-factor authentication. </p>
<p>HOTP and TOTP are both different one-time password schemes used by either hardware security keys or 2FA apps like Google Authenticator. You'll have seen it in action if you use a tool like Aegis or Raivo where you get resetting passcodes that you copy and paste into your browser every 30 seconds. </p>
<p>The difference between the two is that the HOTP code scheme tends to be used with hardware security keys and increments per use. But this leaves a longer time window where an attacker can breach the code. </p>
<p>Time-based systems only give you between 30 seconds to 60 seconds to login with the code, but the user is given enough time to retry codes given such a short window. Some of the most secure elements combine both HOTP and a time-based window. </p>
<p><strong>Takeaway</strong>: Probably the best things you can do for your digital security right now are: </p>
<ul>
<li>Have a password manager system that allows you to avoid password reuse</li>
<li>Have two-factor authentication either through an app (such as Aegis or Raivo) or if you're willing to invest, a hardware security key like a Yubico. </li>
</ul>
<h2 id="heading-2-choose-your-browser-wisely">2: Choose Your Browser Wisely</h2>
<p>Next, you'll want to think about the browser you’re using and what data you're revealing about yourself.</p>
<h3 id="heading-use-a-security-focused-browser">Use a Security-focused Browser</h3>
<p>The browser you use to access the Internet stores data about you and shares data about who you are and what your interests are. Your choice of browser and the extensions you load will determine how much ad tracking you allow through, as well as the number of cookies. </p>
<p>A default installation of Firefox, Chrome, or Safari won't have much in the way of privacy-preserving features. But you can download extensions such as Privacy Badger, https everywhere, and uBlock Origin to help you better defend your online privacy and security. </p>
<p>These tools will serve as script-blockers and ad-blockers, as well as a guarantee that you'll be browsing sites where your data is encrypted – an important consideration when we get to point 3. </p>
<h3 id="heading-consider-using-a-vpn">Consider using a VPN</h3>
<p>Also, if you're using your regular Internet without a VPN or without using a service like Tor, you're likely revealing your IP address and your MAC address. </p>
<p>The IP address is malleable, but can reveal roughly where you are. IPInfo, for example, shows that you can tie an IP address <a target="_blank" href="https://ipinfo.io/ip-address-information">to your location</a> with the latitude and longitude represented, the company providing your Internet, and perhaps the business that owns the IP address. </p>
<p>Your MAC address is tied to your device and is relatively static. When you put on a VPN or use Tor, you can show a different IP address than the one tied to your home network or insecure open networks like the Wifi at your local coffee shop. But depending on the VPN you use, you could be giving them access to every site you visit – so it's important to ensure that you work with a provider that has a no-logs policy such as MullvadVPN. </p>
<p><strong>Takeaway</strong>: If you're concerned about digital privacy and security, use a privacy-focused browser variant either on desktop or mobile. This could be something like Librewolf and Duckduckgo on mobile. </p>
<p>Your default search engine should not be Google. It should be Duckduckgo or a more privacy-focused variant (though note that Duckduckgo will still serve ads through Microsoft's ad exchange). </p>
<p>You should also understand the implications of giving off your IP address and MAC address. Make sure you evaluate whether or not using Tor or a VPN makes sense for you. Consider carefully the VPN you choose. </p>
<h2 id="heading-3-understand-encryption-and-what-it-means">3: Understand Encryption and What it Means</h2>
<p>The term "Encryption" is often bandied about. But you might be wondering how it really matters to you. </p>
<p>Well, when it comes to digital privacy and security, understanding the difference between https:// and http://, cleartext vs. hashed text, and end-to-end encryption matters a lot.</p>
<h3 id="heading-http-vs-https">HTTP vs HTTPS</h3>
<p>Let's start with https:// over http://. Why does it matter what type of site you're browsing? </p>
<p>HTTP powers the web. Essentially, when you're browsing the Internet, under the hood your device is making a series of HTTP requests to servers you direct it to. With regular http:// traffic, however, anytime somebody sees HTTP requests and communications, <a target="_blank" href="https://www.cloudflare.com/learning/ssl/why-is-http-not-secure/">they can see the text within</a>. This means that if you were sending passwords, credit card information, or other sensitive communications, it would be trivial to intercept those messages. </p>
<p>HTTPS, on the other hand, signs HTTP with encryption keys using a <a target="_blank" href="https://www.freecodecamp.org/news/what-is-tls-transport-layer-security-encryption-explained-in-plain-english/">method called TLS</a>. The short of it is that if you're using https:// and browsing sites everywhere with https:// (which an extension like HTTPs Everywhere can help force), that you're less likely to leak your data to attackers.</p>
<h3 id="heading-cleartext-vs-hashed-text">Cleartext vs Hashed Text</h3>
<p>You'll often hear about cleartext vs hashed text when it comes to explaining a password breach. Cleartext means that if an attacker gets ahold of password data, they have your password in its full-text form. If it's hashed, that means the attacker will get a bunch of symbols that aren't your password but perhaps with some work, they can get to your password in plaintext. </p>
<p>If a website is storing your passwords in plaintext, it means that attackers that get a database full of passwords will be able to easily use that stash right away. A cleartext/plaintext leak means that you need to immediately change your passwords with much more urgency, though even if a password is hashed, you should still switch it over. </p>
<p>Services like haveibeenpwned.com will help you determine which password leaks apply to an email – and it's good to check every once in a while to see if you have any compromised credentials (some password managers will automatically check this for you as well.).</p>
<p>End-to-end encryption is a technical term that seems complex but delivers a simple promise: within the codebase, only the sender and receiver of a message will be able to see and decrypt the original message. This means that the service the messages are hosted on can't see what is being transmitted, and therefore can't send over that information to anybody. </p>
<p>Services like Signal offer end-to-end encryption by default (including in group chats) and are seen as the gold standard. WhatsApp also offers end-to-end encryption by default, though its association with Meta sometimes gets privacy advocates wary. </p>
<p>Other services offer variants, but you have to trigger them – for example, Telegram has end-to-end encryption for "Secret chats", but not group chats and non-secret private chats. </p>
<p><strong>Takeaway</strong>: Make sure you're browsing on https:// sites with a browser extension (<a target="_blank" href="https://www.eff.org/https-everywhere">HTTPs Everywhere</a>). Also, check to see if your passwords have been compromised and how they've been compromised with <a target="_blank" href="https://haveibeenpwned.com/">HaveIBeenPwned.com</a>. And stick to end-to-end encryption on chat and communications if you want to make sure the people you want to see your communications are the only ones that do. </p>
<h2 id="heading-4-how-you-spend-your-money-digitally-leaves-a-trace">4: How You Spend Your Money Digitally Leaves a Trace</h2>
<p>Online, one frontier for digital privacy is how you spend and own money. In the analog world, you can spend cash and rest assured that it is unlikely that your transaction will be traced back to you. </p>
<p>In the digital world, however, you have the burden of a credit card or debit card linked back to your address and names for every transaction you do. While online security has been developed to ensure that these don't leak (though they still can and have), there are also new ways to transact online with a (relatively) privacy-preserving option: Bitcoin, Lightning Network. </p>
<p>Lightning Network is a second layer technology built on Bitcoin that doesn't record its transactional flow between nodes on-chain, but rather settles channel opens/closes on it. This allows you to transact Bitcoin rapidly, without a fee, and not have your each transaction show up on the Bitcoin chain. </p>
<p>Now, the nuances of how to use tools like Lightning Network and Bitcoin in a way that preserves privacy merits a much fuller discussion – but be aware that a tradeoff now exists. </p>
<p>Yes, using Bitcoin will expose you to broadcasting your transactions over a public ledger, one scanned by perhaps millions of people. But it will also allow you to transact with the IP address of your choice, the device of your choice, and the identity of your choice. It's up to you to do the legwork and determine if that's a tradeoff worth having. </p>
<p><strong>Takeaway</strong>: Be aware that there are alternatives to using a credit card or debit card online for all of your payments that are closer to how you might use cash in the analog world. </p>
<h2 id="heading-5-the-devices-you-use-do-matter-for-privacy-and-security">5: The Devices You Use Do Matter for Privacy and Security</h2>
<p>Lastly, the devices you're using do matter for privacy and security. The Internet is a tradeoff: you get access to many different services, but you subject the devices you're using to access these services to giving off and receiving data. </p>
<p>Most of the commercialized laptops and phones out there have privacy and security features built in. An example of this is hardware changes that make recent iPhones more resilient, or frequent security updates for the operating system in question, from Linux, Microsoft, to Mac, to iOS and Android. </p>
<p>The tradeoff with devices, though, tends to be the expense, cost, and maintenance. In theory, having a second device on both laptop and mobile (for travel purposes, for example, to avoid border seizures) is ideal. And you may want to experiment with different operating systems – for example, the privacy-focused GrapheneOS for mobile, and System76 or Pinebooks for Linux-based laptops. </p>
<p>You might even go further and decide to experiment with home-based servers to run your own services. </p>
<p>Ultimately, the choice is yours: the cost of experimentation here can be high in terms of time and money spent, but can be well-worth it to maintain control over your own devices and data. </p>
<p><strong>Takeaway</strong>: Consider the devices you use. Make sure you're on top of security updates, and determine how and which devices you want to use going forward. </p>
<h2 id="heading-wrapping-up">Wrapping Up</h2>
<p>If you're interested in learning a bit more about how your digital security and privacy stacks up, <a target="_blank" href="https://loki2100.limesurvey.net/948232?lang=en">this assessment will</a> help you determine your level and give you specific recommendations. </p>
<p>The most important thing about digital security and privacy is to be mindful of the tradeoffs, and to consider and often re-evaluate best practices in an actively evolving ecosystem.   </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Optimize Your Database – Optimization Principles and Best Practices ]]>
                </title>
                <description>
                    <![CDATA[ Databases are an integral component of building applications, whether web, desktop or mobile. They symbolically serve as the mitochondria of the application, as their primary function is to manage data. Database management is a critical skill a devel... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/database-optimization-principles/</link>
                <guid isPermaLink="false">66bb58c3965d5c9ed5487ba2</guid>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ database ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Oluwatobi ]]>
                </dc:creator>
                <pubDate>Fri, 10 May 2024 15:21:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/05/Acid.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Databases are an integral component of building applications, whether web, desktop or mobile. They symbolically serve as the mitochondria of the application, as their primary function is to manage data.</p>
<p>Database management is a critical skill a developer must possess in building scalable applications that have a high level of efficiency. If not handled properly, it can result in data loss and mismanagement on the part of the database developer.</p>
<p>Hence, databases must be structured and built with the users in mind and built utilizing the best practices available.</p>
<p>This article aims to highlight general principles of database best practices and also explain each peculiarity. But before we discuss that in detail, let’s review what database transactions are all about.</p>
<h2 id="heading-what-are-database-transactions">What are Database Transactions?</h2>
<p>Database transactions are simply groups of operations which can be termed as a unit of a work process performed on a database within a database management system. </p>
<p>It encompasses basic operations such as CRUD operations to more advanced operations such as database indexing, caching, and normalization.</p>
<p>With so many users performing many transactions at the same time, it’s important to ensure that the database is concurrency-enabled to prevent data interference between two or more users accessing the same resource. </p>
<p>Hence, there is the need for the ACID principle.  What then does ACID represent?</p>
<ul>
<li>Atomicity</li>
<li>Consistency</li>
<li>Isolation</li>
<li>Durability</li>
</ul>
<p>Subsequently, we will be discussing each point in detail. First on our list is atomicity.</p>
<h2 id="heading-what-is-the-database-atomicity-principle">What is the Database Atomicity Principle?</h2>
<p>What does database atomicity entail? The atomicity of a database simply means that a database operation can’t be broken down further as a unit. This means that the database operation or transactions gets executed completely, and in case any error comes up during the execution process, the entire operation gets completely cancelled, preventing room for partial operation execution.</p>
<p>If the database isn’t atomic, this can result in the provision of misleading incomplete data and ultimately result in entire system chaos. How does the database ensure atomicity? It does this by creating a copy of the existing database before the operation gets executed and then initiates a crash recovery and backup restoration operation in the event of an operation failure.</p>
<p>It is also important to note that other database principles such as consistency and durability rely on the need for the database to be atomic to be truly fulfilled.</p>
<p>Having discussed this, let’s move on to the database consistency principle.</p>
<h2 id="heading-what-is-the-database-consistency-principle">What is the Database Consistency Principle?</h2>
<p>This principle entails that the database has certain constraints, cascades, triggers and other requirements in place, which needs to be fulfilled while making changes to an established database. Failure to fulfill this requirement will lead to consistency errors, returning the database to its previous stable state.</p>
<p>Also, consistency as a principle ensures that the data updated by a user is made available as the latest version of the data in the database to all users who desire to read the database. Having this in place eliminates the occurrence of inconsistencies and aids faster information retrieval.</p>
<p>Understanding what it means for a database to be consistent involves ensuring the operation performed on the database passes the integrity check before being successfully executed. Having exhausted this in detail, let's discuss the database isolation principle.</p>
<h2 id="heading-what-is-the-database-isolation-principle">What is the Database Isolation Principle?</h2>
<p>Why should we isolate a database and how does one make a database operation independent from other database operations?</p>
<p>Isolation is necessary in a database management system to ensure that the user's access to information on the database is not interfered with by other concurrent transactions undertaken by other users on the database. To enforce this, the use of isolation levels in each database operation helps to preserve information integrity.</p>
<p>To effectively guarantee the database integrity, specific database isolation levels must be used. Here are some of the isolation levels ranked in order of hierarchy:</p>
<ul>
<li>Read uncommitted</li>
<li>Read committed</li>
<li>Repeatable read</li>
<li>Serializability</li>
</ul>
<h3 id="heading-read-uncommitted-isolation-level">Read Uncommitted Isolation Level</h3>
<p>The read uncommitted database isolation level allows other users to have access to read current database transactions which has not yet been completely or successfully executed. It allows access to read what is being referred to as dirty read, which is one of the data inconsistencies that can be seen. This level of data isolation isn’t advised.</p>
<h3 id="heading-read-committed-isolation-level">Read Committed Isolation Level</h3>
<p>This database isolation level disallows other users to read or have access to a database transaction that has not yet been committed. Hence it prevents other users from seeing, updating or overwriting it until it has been completely executed.</p>
<h3 id="heading-repeatable-read-isolation-level">Repeatable Read Isolation Level</h3>
<p>This isolation level exclusively isolates a transaction from other transactions occurring concurrently, preventing other users access to read and update the transactions.</p>
<h3 id="heading-serializability-isolation-level">Serializability Isolation Level</h3>
<p>This is the highest level of data isolation and is referred to as the strictest level. It isolates the multiple transactions performed concurrently and executes them efficiently as they are executed serially. It also prevents database inconsistencies.</p>
<p>Without these levels in place, inconsistent database mishaps such as dirty reads, non-repeatable reads, phantom reads and many others may be experienced. With this, let's move on to the last point about database durability and discuss it in detail.</p>
<h2 id="heading-what-is-the-database-durability-principle">What is the Database Durability Principle?</h2>
<p>What does it imply when we describe a database as durable and how do we ensure the durability of a database? Durability as it sounds is a principle which ensures that databases have a high level of immortality.</p>
<p>Irrespective of any adverse outcomes that the database management system might face such as outages and crashes, there shouldn't be any loss of database information.</p>
<p>How do databases try to achieve this? The database creates a transactional log that contains the recorded data before any new operation gets executed. In the event of any of these adverse events, the transaction log serves as the backup store, ensuring that the database info is well preserved up to the point before the operation occurred, thereby mitigating against data breaches and loss.</p>
<p>We'll also highlight other helpful database operations best practices that can also be implemented.</p>
<h2 id="heading-other-database-operations-best-practices">Other Database Operations Best Practices</h2>
<p>The BASE principle, which is more suited for NoSQL databases such as MongoDB, Redis, and Cassandra, and so on. It entails a database to be:</p>
<ul>
<li>Basically available</li>
<li>Existing in a soft state</li>
<li>And be eventually consistent.</li>
</ul>
<h3 id="heading-basically-available">Basically Available</h3>
<p>This entails that the database prioritizes the availability of the database operations over consistency and concurrency. This is quite applicable to distributed systems which rely on a high level of efficiency to function effectively.</p>
<h3 id="heading-soft-state">Soft State</h3>
<p>This ensures easy flexibility of the database, allowing for size scaling, operations and increased concurrency for optimal database performance at all times. This allows the data to maintain resiliency.</p>
<h3 id="heading-eventually-consistent">Eventually Consistent</h3>
<p>This entails that, irrespective of how the transactions get executed in the sequences, it eventually achieves efficient consistency. This is achieved by conflict resolution and reconciliation. This eventually contributes to the building of a resilient data system.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>With this, we have come to the end of the tutorial. We hope you’ve learned essentially about optimizing database operations and their efficiency using the ACID principle and other best practices available.</p>
<p>Feel free to drop comments and questions in the box below, and also check out my other articles <a target="_blank" href="https://www.freecodecamp.org/news/p/2a9a2ef7-b659-4655-97ce-fea0f3a9f668/linktr.ee/tobilyn77">here</a>. Till next time, keep on coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Write Accessible Technical Documentation – Best Practices with Examples ]]>
                </title>
                <description>
                    <![CDATA[ When you're writing technical documentation for a project or a tool you're working on, you'll want it to be accessible. This means that it will cater to and be usable by the diverse global audience on the web. Web accessibility aims to make it possib... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/best-practices-for-writing-accessible-technical-documentation/</link>
                <guid isPermaLink="false">66d84fe57211ea6be29e1b6d</guid>
                
                    <category>
                        <![CDATA[ a11y ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ documentation ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ EZINNE ANNE EMILIA ]]>
                </dc:creator>
                <pubDate>Thu, 11 Apr 2024 23:03:04 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/20240401_161256_0000.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When you're writing technical documentation for a project or a tool you're working on, you'll want it to be accessible. This means that it will cater to and be usable by the diverse global audience on the web.</p>
<p>Web accessibility aims to make it possible for anyone to access web content. There are common accessibility best practices for designers, developers, and writers. This article will cover some best practices for creating technical content.‌</p>
<h2 id="heading-what-is-web-accessibility">What is Web Accessibility?</h2>
<p><a target="_blank" href="https://www.freecodecamp.org/news/web-accessibility-for-devs/">Web accessibility</a> is the practice of making it possible for anyone to consume or create content on the web, regardless of any health, economic, geographic, or language challenges they may have.</p>
<h2 id="heading-why-is-web-accessibility-important">Why is Web Accessibility Important?</h2>
<p>It is important to apply web accessibility best practices in your projects for a number of reasons.</p>
<p>First, it'll help you reach a wider audience. When a person who may have different abilities comes across some data on the web – say on your website – they'll want to learn more or use the data. But if they are not able to access it, you will not be happy or have a good experience.</p>
<p>Imagine how many people are unable to utilize the web because they are not considered when devs and designers are making decisions about how the product, website, or tool will be built.</p>
<p>Another important thing about accessibility is that it improves your brand's quality. Letting people know you are an accessibility-oriented person or company by implementing it in your work shows that you want your information to be available t everyone. It also displays your versatility in your craft and your ability to improve and adapt with changing times and trends.</p>
<p>Also, as an individual, applying accessibility best practices benefits you as well. There are possible employment opportunities for developers and designers with great accessibility skills.</p>
<p>Good accessibility practices mean good SEO practices too, which can result in more visibility for your work.</p>
<p>Finally, accessibility is enforced by law in certain countries around the world, and web accessibility strategies are implemented by certain countries. There could be legal consequences if you overlook accessibility on your websites and apps.</p>
<h2 id="heading-how-to-write-accessible-technical-documentation">How to Write Accessible Technical Documentation</h2>
<p>Software engineers have a key role in making the web accessible. But when it comes to writing documentation, technical writers also have a role to play in improving web accessibility.</p>
<p>Technical writers help write various types of content, like user guides, tutorials, API references, code documentation, and so on.</p>
<p>Now, let's look at some of the best practices for implementing web accessibility in technical writing. These strategies will help improve your documentation and make it more user-friendly and accessible to everyone.</p>
<h3 id="heading-use-clear-headings-and-paragraphs">Use clear headings and paragraphs</h3>
<p>When writing content, you should make sure to use headings – along with the proper heading hierarchy (H1 for the title of the page/article, H2 for major headings, H3 for subheadings, and so on).</p>
<p>Also, make sure to break your content up into paragraphs so it's easier to read and understand.</p>
<p>When you introduce a new topic, use a heading to call that out. When you talk about smaller topics within that section, use subheadings to alert the reader.</p>
<p>Headings are also important to help screen readers understand a page's contents and how to navigate through them. So use headings to help guide readers through the text in a logical manner.</p>
<p>You denote headings in markdown with hashes. Here's an example of headings in hierarchical order.‌</p>
<pre><code class="lang-css"># <span class="hljs-selector-tag">Use</span> <span class="hljs-selector-tag">H1</span> <span class="hljs-selector-tag">for</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">page</span> <span class="hljs-selector-tag">title</span>

## <span class="hljs-selector-tag">Use</span> <span class="hljs-selector-tag">H2</span> <span class="hljs-selector-tag">for</span> <span class="hljs-selector-tag">major</span> <span class="hljs-selector-tag">headings</span> 
<span class="hljs-selector-tag">This</span> <span class="hljs-selector-tag">heading</span> <span class="hljs-selector-tag">is</span> <span class="hljs-selector-tag">a</span> <span class="hljs-selector-tag">main</span> <span class="hljs-selector-tag">heading</span> <span class="hljs-selector-tag">for</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">main</span> <span class="hljs-selector-tag">section</span> <span class="hljs-selector-tag">content</span>. 

### <span class="hljs-selector-tag">Use</span> <span class="hljs-selector-tag">H3</span> <span class="hljs-selector-tag">for</span> <span class="hljs-selector-tag">subheadings</span> 
<span class="hljs-selector-tag">This</span> <span class="hljs-selector-tag">heading</span> <span class="hljs-selector-tag">is</span> <span class="hljs-selector-tag">a</span> <span class="hljs-selector-tag">subheading</span> <span class="hljs-selector-tag">that</span> <span class="hljs-selector-tag">goes</span> <span class="hljs-selector-tag">deeper</span> <span class="hljs-selector-tag">into</span> <span class="hljs-selector-tag">one</span> <span class="hljs-selector-tag">of</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">main</span> <span class="hljs-selector-tag">section</span>'<span class="hljs-selector-tag">s</span> <span class="hljs-selector-tag">points</span>.
</code></pre>
<h3 id="heading-make-your-content-clear-and-concise">Make your content clear and concise</h3>
<p>Overall, try to keep your sentences quite short in your docs. This makes them easier to read and understand (for everyone). You can also use images or videos to provide more details if needed.</p>
<p>Make sure you give the full meanings of any acronyms you are using for the first time. Also, always use simple sentences, and try not to use ambiguous words.</p>
<p>Here's an example of an overly complex, long sentence with difficult vocabulary:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">The</span> <span class="hljs-selector-tag">web3</span> <span class="hljs-selector-tag">running</span> <span class="hljs-selector-tag">on</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">Blockchain</span> <span class="hljs-selector-tag">structure</span> <span class="hljs-selector-tag">which</span> <span class="hljs-selector-tag">is</span> <span class="hljs-selector-tag">transparent</span>, <span class="hljs-selector-tag">secure</span>, <span class="hljs-selector-tag">immutable</span>, <span class="hljs-selector-tag">decentralized</span> <span class="hljs-selector-tag">would</span> <span class="hljs-selector-tag">require</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">processes</span> <span class="hljs-selector-tag">of</span> <span class="hljs-selector-tag">artificial</span> <span class="hljs-selector-tag">intelligence</span>, <span class="hljs-selector-tag">where</span> <span class="hljs-selector-tag">it</span> <span class="hljs-selector-tag">would</span> <span class="hljs-selector-tag">read</span> <span class="hljs-selector-tag">data</span>, <span class="hljs-selector-tag">process</span>, <span class="hljs-selector-tag">and</span> <span class="hljs-selector-tag">store</span> <span class="hljs-selector-tag">information</span>.
</code></pre>
<p>This is better:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">Web3</span> <span class="hljs-selector-tag">is</span> <span class="hljs-selector-tag">built</span> <span class="hljs-selector-tag">on</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">transparent</span>, <span class="hljs-selector-tag">secure</span>, <span class="hljs-selector-tag">unchangable</span>, <span class="hljs-selector-tag">and</span> <span class="hljs-selector-tag">decentralized</span> <span class="hljs-selector-tag">structure</span> <span class="hljs-selector-tag">of</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">blockchain</span>. <span class="hljs-selector-tag">It</span> <span class="hljs-selector-tag">uses</span> <span class="hljs-selector-tag">artificial</span> <span class="hljs-selector-tag">intelligence</span> <span class="hljs-selector-tag">processes</span> <span class="hljs-selector-tag">to</span> <span class="hljs-selector-tag">read</span>, <span class="hljs-selector-tag">process</span>, <span class="hljs-selector-tag">and</span> <span class="hljs-selector-tag">store</span> <span class="hljs-selector-tag">information</span>.
</code></pre>
<p>Your content should contain the main points you're trying to make, removing all forms of ambiguity.‌ ‌</p>
<h3 id="heading-use-informative-link-text">Use informative link text</h3>
<p>All your in-line links should use clear, detailed, and descriptive text. You can describe the link's purpose or the company's name if it is a brand, for example.</p>
<p>Links are important for improving the ranking of a page. And using links like "Click here" or "Read More" is not all that helpful, as they don't tell the reader much about what they'll find at that link.</p>
<p>For instance, if I wanted to link a W3C (World Wide Web Consortium) accessibility tutorial to this article, I could use the following format: Check out <a target="_blank" href="https://www.w3.org/WAI/roles/writers/">these resources for content writers by W3C</a>.</p>
<h3 id="heading-add-alt-text-and-captions-to-media-content">Add alt text and captions to media content</h3>
<h4 id="heading-images">Images</h4>
<p>Adding descriptive text to the alt text attribute allows screen readers to be able to read out the alt text associated with an image. Alt text also helps search engine bots that crawl the page know how to classify that content.</p>
<p>When you're adding alt text, describe the purpose of the image and not what the image is. For instance, let's say you're using an image that shows some shipping containers in a section that is about containerization.‌</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/containers-1.jpeg" alt="Various containers on a ship in motion to illustrate the packaging structure and process of a digital container." width="600" height="400" loading="lazy"></p>
<p><em>Various containers on a ship in motion to illustrate the packaging structure and process of a digital container.</em></p>
<p>Instead of writing alt text like "various containers on a ship in motion", you could write "various containers on a ship in motion to illustrate the packaging structure and process of a digital container."</p>
<p>While alt text serves as an alternative for the image, captions give more details about the image. You can use HTML to insert image captions. Markdown does not support image captions, but markdown documentation sites usually have a way around it (for example, through plugins – ReadTheDocs, MkDocs – or inserting HTML via a custom component –Docusaurus).</p>
<p>As an example, I'll show you how to add image captions in Docusaurus.</p>
<p><strong>How to add image captions in a Docusaurus .md file:</strong></p>
<ul>
<li><p>Create a folder <code>components</code> in the <code>src</code> folder.</p>
</li>
<li><p>Create a file named <code>figure.jsx</code>.</p>
</li>
<li><p>Add this line of code to it:</p>
</li>
</ul>
<pre><code class="lang-css"><span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">React</span> <span class="hljs-selector-tag">from</span> "<span class="hljs-selector-tag">react</span>"; 
<span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">useBaseUrl</span> <span class="hljs-selector-tag">from</span> "<span class="hljs-keyword">@docusaurus</span>/useBaseUrl"; 
<span class="hljs-selector-tag">export</span> <span class="hljs-selector-tag">default</span> <span class="hljs-selector-tag">function</span> <span class="hljs-selector-tag">Figure</span>({ src, caption }) {
  return ( 
  &lt;figure&gt; &lt;img src={useBaseUrl(src)} <span class="hljs-selector-tag">alt</span>={caption} /&gt; 
  &lt;<span class="hljs-selector-tag">figcaption</span>&gt;{`<span class="hljs-attribute">Figure</span>: ${caption}`}&lt;/<span class="hljs-selector-tag">figcaption</span>&gt; &lt;/<span class="hljs-selector-tag">figure</span>&gt; 
  ); 
}
</code></pre>
<ul>
<li>Go to the <code>.md</code> file where you have the image and import the code.</li>
</ul>
<pre><code class="lang-css"><span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">Figure</span> <span class="hljs-selector-tag">from</span> '<span class="hljs-keyword">@site</span>/src/components/figure'; 
<span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">figure1</span> <span class="hljs-selector-tag">from</span> '<span class="hljs-selector-tag">path-to-image</span>';
</code></pre>
<ul>
<li>Add it to the file.</li>
</ul>
<pre><code class="lang-css">&lt;<span class="hljs-selector-tag">Figure</span> <span class="hljs-selector-tag">caption</span>="<span class="hljs-selector-tag">This</span> <span class="hljs-selector-tag">is</span> <span class="hljs-selector-tag">a</span> <span class="hljs-selector-tag">caption</span> <span class="hljs-selector-tag">for</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">image</span>" <span class="hljs-selector-tag">alt</span>="<span class="hljs-selector-tag">This</span> <span class="hljs-selector-tag">is</span> <span class="hljs-selector-tag">alt</span> <span class="hljs-selector-tag">text</span>" <span class="hljs-selector-tag">src</span>={figure1} /&gt;
</code></pre>
<p>The image will now display with a caption.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_13-3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>A screenshot example of image caption</em></p>
<h4 id="heading-videos">‌Videos</h4>
<p>To caption videos, HTML is a great option. But if you are using markdown, you can embed videos from YouTube and Vimeo using the <code>&lt;iframe&gt;</code> tag. These apps offer in-built caption support so you can enable captions before adding the embed code.</p>
<p>You could also install third-party plugins for this purpose.</p>
<p>Here's another tip: avoid flashing content in your videos as it could lead to seizure triggers. If your video has flashing bright colours, ensure that it does not exceed two times within a second.</p>
<h3 id="heading-add-transcripts-to-audios-and-videos">Add transcripts to audios and videos</h3>
<p>It's a good idea to add transcripts to your audio and video content. Not everyone will want to watch or listen to the content. But they may be curious to know what it is about.</p>
<p>By adding a transcript, you make it easier for anyone to navigate through the content and get the information that they need.</p>
<h4 id="heading-transcript-for-audio">Transcript for audio</h4>
<p>For audio content, you can insert transcripts using HTML. Here's an example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">audio</span> <span class="hljs-attr">controls</span> <span class="hljs-attr">muted</span>&gt;</span><span class="hljs-comment">&lt;!--Always set your audios to muted--&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">source</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"ringtone.mp3"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"audio/mpeg"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">source</span>&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">audio</span>&gt;</span> 
<span class="hljs-tag">&lt;<span class="hljs-name">code</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Here is a transcription of the text<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> 
    00:03 = I am going to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:05 = I am going to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:08 = I am going to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:10 = I need to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:11 = I have to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:13 = I should be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:16 = I am going to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:18 = I ought to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:21 = I have to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:23 = Productivity matters to me <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">code</span>&gt;</span>
</code></pre>
<p>For markdown documentation sites like Docusaurus, you can create a custom component.‌</p>
<ul>
<li><p>In your <code>src/components</code> folder, create a file named <code>transcript.jsx</code>.</p>
</li>
<li><p>Insert this code:</p>
</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>; 
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Transcript</span>(<span class="hljs-params">{ }</span>) </span>{ 
  <span class="hljs-keyword">const</span> [showTranscript, setShowTranscript] = useState(<span class="hljs-literal">false</span>); 
  <span class="hljs-keyword">const</span> toggleTranscript = <span class="hljs-function">() =&gt;</span> { 
    setShowTranscript(!showTranscript); 
  }; 
  <span class="hljs-keyword">return</span> ( 
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{toggleTranscript}</span>&gt;</span> { 
    showTranscript ? 'Hide transcript' : 'View transcript'
    } 
    <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span> {showTranscript &amp;&amp; ( <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"transcriptText"</span>&gt;</span> (insert your transcript text here) <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> )} 
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span> 
  ); 
}
</code></pre>
<ul>
<li>Go to your markdown file and import it.</li>
</ul>
<pre><code class="lang-css"><span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">Transcript</span> <span class="hljs-selector-tag">from</span> '<span class="hljs-keyword">@site</span>/src/components/transcript'; 

&lt;<span class="hljs-selector-tag">Transcript</span> /&gt;
</code></pre>
<p>‌</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_17-6.png" alt="A screenshot of the audio transcript output on a documentation site" width="600" height="400" loading="lazy"></p>
<p><em>A screenshot of the audio transcript output</em></p>
<p>‌<strong>Note:</strong> I added some tweaks to the code to make transcript display optional. You can edit it if you want the transcript to show as the page loads.</p>
<h4 id="heading-transcript-for-video">Transcript for video</h4>
<p>Now for videos, YouTube is a great option. It provides inbuilt transcripts for your videos. So, you can always embed YouTube videos in your docs.</p>
<p>The transcript is in the video description after the main details. The transcript will display with the timestamps when you click the "Show Transcript" button.</p>
<h3 id="heading-add-code-snippets-and-use-the-colour-contrast-technique">Add code snippets and use the colour contrast technique</h3>
<h4 id="heading-how-to-add-code-snippets">How to add code snippets</h4>
<p>Use code blocks within the text to explain code instead of images. You could also use code snippets to showcase the output of your code. Unless it is necessary to add an image, you should use code snippets.</p>
<p>For instance,</p>
<p><code>index.html</code></p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span> 
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"content-type"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"text/html; charset=utf-8"</span> /&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>A calculator app<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"styles.css"</span>/&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>This will allow screen readers to read through the code, which they are not able to do with screenshots.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_14-2.png" alt="A screenshot of the above code" width="600" height="400" loading="lazy"></p>
<p><em>A screenshot of the above code</em></p>
<h4 id="heading-colour-contrast-technique">Colour contrast technique</h4>
<p>The colour contrast technique implies using colours that are opposite or heavily contrasting.</p>
<p>For example, using black text on a white background has a high contrast, as opposed to using light brown text on a brown background.</p>
<p>When combining colours, you could use an <a target="_blank" href="http://colorsafe.co/">accessible colour palette like Color Safe</a>.‌</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_15-4.png" alt="Using a pale white colour on a green background gotten from Color Safe" width="600" height="400" loading="lazy"></p>
<p><em>Using a pale white colour on a green background gotten from Color Safe</em></p>
<h3 id="heading-add-translation-options">Add translation options</h3>
<p>There are documentation sites that provide translation options where you can build your docs in multiple languages, websites like Jekyll. <a target="_blank" href="https://leo3418.github.io/collections/multilingual-jekyll-site/add-language-switcher.html">This is an example</a>.</p>
<p>Docusaurus is also another doc site that provides multilingual options using Crowdin or Git.</p>
<ul>
<li><p><a target="_blank" href="https://docusaurus.io/docs/i18n/git">Follow through this guide</a> to set up translation and localization on Docusaurus using Git.</p>
</li>
<li><p><a target="_blank" href="https://docusaurus.io/docs/i18n/crowdin">Follow through this guide</a> to set up translation and localization on Docusaurus using Crowdin.‌</p>
</li>
</ul>
<h3 id="heading-use-accessibility-testing-tools">Use accessibility testing tools</h3>
<p>There are tools you can use to check for errors in accessibility in your docs. Some examples are <a target="_blank" href="https://wave.webaim.org/">WAVE (Web Accessibility Evaluation Tool)</a> and <a target="_blank" href="https://www.deque.com/axe/">AXE (Accessibility Engine)</a>.</p>
<p>Also, you can get the <a target="_blank" href="https://www.nvaccess.org/download/">NVDA(NonVisual Desktop Access) screen reader</a> to test out your content. This software will let you know how the content of your documentation will be perceived by a user using a screen reader.‌</p>
<h3 id="heading-set-up-an-improvement-or-suggestion-box">Set up an improvement or suggestion box</h3>
<p>Finally, it may not be possible to cover the needs of every user. So you could add a suggestion or improvement box, allowing users to send feedback about how you could further improve the content. Hearing firsthand from users can help you know how best to make the docs accessible for them.</p>
<p>To add an improvement box, you could use an external form link that stores the users' inputs or you could set up the suggestion box in the docs.</p>
<h4 id="heading-how-to-add-an-external-form-link-in-docusaurus">How to add an external form link in Docusaurus</h4>
<p>You would need to create a custom component for that.</p>
<ul>
<li><p>Go to <code>src/components</code> folder and create a file <code>feedback.jsx</code>.</p>
</li>
<li><p>Add this code:</p>
</li>
</ul>
<pre><code class="lang-css"><span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">React</span> <span class="hljs-selector-tag">from</span> '<span class="hljs-selector-tag">react</span>'; 

<span class="hljs-selector-tag">export</span> <span class="hljs-selector-tag">default</span> <span class="hljs-selector-tag">function</span> <span class="hljs-selector-tag">FeedbackButton</span>({ href }) {
  return ( &lt;a href={href} <span class="hljs-selector-tag">target</span>="_<span class="hljs-selector-tag">blank</span>" <span class="hljs-selector-tag">rel</span>="<span class="hljs-selector-tag">noopener</span> <span class="hljs-selector-tag">noreferrer</span>" &gt; <span class="hljs-selector-tag">Give</span> <span class="hljs-selector-tag">Feedback</span> &lt;/<span class="hljs-selector-tag">a</span>&gt; ); 
};
</code></pre>
<ul>
<li>In your markdown file import it:</li>
</ul>
<pre><code class="lang-css"><span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">FeedbackButton</span> <span class="hljs-selector-tag">from</span> '<span class="hljs-keyword">@site</span>/src/components/feedbackbutton';
</code></pre>
<ul>
<li>Insert the link</li>
</ul>
<pre><code class="lang-css">&lt;<span class="hljs-selector-tag">FeedbackButton</span> <span class="hljs-selector-tag">href</span>="<span class="hljs-selector-tag">https</span>://<span class="hljs-selector-tag">forms</span><span class="hljs-selector-class">.google</span><span class="hljs-selector-class">.com</span>" /&gt;
</code></pre>
<p>When you run it on your docs, it should showcase a link to Google forms. Google Forms is an example, you could add the link to your company website or server. Here's what it'll look like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_18-3.png" alt="A feedback link that states &quot;Give feedback&quot; for suggestion or improvement on a docusaurus docs site that leads users to an external site which is Google Forms" width="600" height="400" loading="lazy"></p>
<p><em>A feedback link for suggestion in a docs site</em></p>
<h2 id="heading-summary">Summary</h2>
<p>To follow and implement these accessibility best practices, you can consider creating or using an already made style guide. This can help you consistently implement these practices and make it easier for you and other technical writers on your team.</p>
<p>There are style guides focused on accessibility for technical writers, such as the following:</p>
<ol>
<li><p><a target="_blank" href="https://github.com/heyawhite/tech-writing-tools/blob/main/accessibility/style.md">Accessibility style guide by Heyawhite</a></p>
</li>
<li><p><a target="_blank" href="https://developers.google.com/style/accessibility">Write accessible documentation by Google for developers</a></p>
</li>
<li><p><a target="_blank" href="https://styleguide.mailchimp.com/writing-for-accessibility/">Writing for Accessibility by MailChimp content style guide</a></p>
</li>
</ol>
<p>That sums up my tips about web accessibility practices in writing. I'm a technical writer, and you can reach out to me on <a target="_blank" href="https://www.instagram.com/ezinneanneemilia/">Instagram</a> or hire me via <a target="_blank" href="https://www.upwork.com/freelancers/~013e195fa64f8b3456?mp_source=share">Upwork</a>. Thank you for reading.‌</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is Reactive Programming? Beginner's Guide to Writing Reactive Code ]]>
                </title>
                <description>
                    <![CDATA[ Welcome to your journey through the dynamic world of reactive programming! This fascinating paradigm is all about building responsive, resilient, and adaptable applications that effortlessly manage vast amounts of data almost instantly. Imagine writi... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/reactive-programming-beginner-guide/</link>
                <guid isPermaLink="false">66ba57fdbca875d7790d6a89</guid>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web Development ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Pacifique Linjanja ]]>
                </dc:creator>
                <pubDate>Mon, 18 Mar 2024 09:02:54 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/03/Screenshot-2024-03-14-at-17.29.29.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Welcome to your journey through the dynamic world of reactive programming! This fascinating paradigm is all about building responsive, resilient, and adaptable applications that effortlessly manage vast amounts of data almost instantly.</p>
<p>Imagine writing a program that needs to react instantly to changes—whether that's user inputs, messages from other systems, or live data feeds. That's where reactive programming shines, making it a cornerstone of modern software development, especially for web and mobile applications.</p>
<p>Let's draw a simple parallel to everyday life to bring this concept closer to home. Consider a bus station, a familiar sight where people queue up, waiting for their ride. Each bus arrival is an event, and the passengers' response—to board the bus—is an action triggered by this event. </p>
<p>Reactive programming works similarly. It deals with data streams (like the schedule of arriving buses) and the propagation of change (a new bus arriving), enabling applications to respond in real-time (just as passengers react by boarding the bus). Sound familiar?</p>
<p>In this article, we'll dive into the essence of reactive programming, focusing on its implementation using JavaScript/TypeScript within the Node.js environment. We'll also keep an eye on a global context that applies to many programming languages and frameworks. </p>
<p>We'll keep things straightforward and engaging, using simple language and practical examples. By the end of this guide, you'll have a solid foundation in reactive programming concepts and hands-on experience building a real-time notification system. </p>
<p>Whether you are new to the concept or looking to refine your skills, this guide is crafted to demystify reactive programming and show you its power in action. Let's get started on this exciting journey together!</p>
<h2 id="heading-what-well-cover"><strong>What We'll Cover:</strong></h2>
<ol>
<li><a class="post-section-overview" href="#heading-understanding-streams-and-observables">Understanding Streams and Observables</a></li>
<li><a class="post-section-overview" href="#heading-reactive-programming-in-javascripttypescript-and-beyond">Reactive Programming in JavaScript/TypeScript and Beyond</a></li>
<li><a class="post-section-overview" href="#heading-how-to-build-a-real-time-notification-system-with-nodejs">How to Build a Real-Time Notification System with Node.js</a><br>– <a class="post-section-overview" href="#heading-introduction-to-the-notification-system">Introduction to the Notification System</a><br>– <a class="post-section-overview" href="#heading-project-setup-getting-started-with-nodejs-and-typescript">Project Setup: Getting Started with Node.js and TypeScript</a><br>– <a class="post-section-overview" href="#heading-how-to-implement-the-core-features-building-a-real-time-notification-system">How to Implement the Core Features</a></li>
<li><a class="post-section-overview" href="#heading-best-practices-and-common-pitfalls">Best Practices and Common Pitfalls</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
<li><a class="post-section-overview" href="#heading-resources">Resources</a></li>
</ol>
<h2 id="heading-understanding-streams-and-observables">Understanding Streams and Observables</h2>
<p>Let's dive into the heart of reactive programming: streams and observables. These concepts are the building blocks of reactive applications, enabling them to process data dynamically and reactively. To understand their significance, let's revisit our bus station analogy.</p>
<p>Imagine the bus station being equipped with a digital display showing real-time updates of bus arrivals, departures, and delays. This display is constantly receiving data about buses - this flow of information is what we call a "stream." Each piece of new data (like the arrival of a bus) can be seen as an "event" in this stream.</p>
<h3 id="heading-streams-the-flow-of-data">Streams: The Flow of Data</h3>
<p>In programming, a stream is a sequence of ongoing data made available over time. Streams can be anything: mouse movements, keystrokes, tweets, or even real-time stock market updates. They're not so different from the bus station's digital display, which receives a continuous flow of information about buses.</p>
<p>In short, a stream is a collection of values pushed over time, the interval between two different values can be controlled (scheduled streams) or random (we never know when someone will send us a message right?). </p>
<p>Streams can emit three different things: a value (of some type), an error, or a "completed" signal. Let’s think of a notification system, for example. On one end we have a client (mobile app, web app, and so on) that has subscribed to a WhatsApp group. Whenever there is a new message in that group, the application will react by sending a push notification to the user–but we never know when those messages are coming.</p>
<p>Figure 1 below shows an illustration of what can be considered as a stream. After some time, the value can change, notifying every client that subscribed to the stream that a new value is available. It gives clients the possibility to unsubscribe at any time they want.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/Guessing-game-Page-4.drawio--1-.png" alt="Image" width="600" height="400" loading="lazy">
<em>Figure 1: Illustration of what is a stream, subscription, and unsubscription</em></p>
<p>As you can see from the image above, from the moment a client unsubscribes, they stop getting new values from the stream.</p>
<h3 id="heading-observables-reacting-to-data">Observables: Reacting to Data</h3>
<p>An observable is a type of stream that you can observe, enabling you to listen for and react to incoming data. </p>
<p>To illustrate, consider the digital display at a bus station as the stream. As you eagerly wait and watch for information about your bus's arrival, you are akin to an observable. When your bus's arrival is displayed (an event), you react by preparing to board it.</p>
<p>Observables are characterized by the following three aspects:</p>
<ol>
<li><strong>Data Lifecycle:</strong> An observable is a primitive type that can contain zero or multiple values. These values are pushed over any duration, determining the lifecycle of the stream.</li>
<li><strong>Cancellable:</strong> Observables can be cancelled at any time. By informing the producer that you no longer require updates, you can cancel a subscription to an observable.</li>
<li><strong>Lazy Evaluation:</strong> Observables are lazy, meaning that they do not perform any actions until you subscribe to them. Similarly, they cease operations when unsubscribed. This stands in contrast to Promises, which are eager and must be settled each time they are invoked before further processing occurs.</li>
</ol>
<h3 id="heading-why-streams-and-observables-are-important">Why Streams and Observables are Important</h3>
<p>Streams and observables are crucial in reactive programming because they allow applications to handle data that changes over time—just like the constantly updating information on the bus station display. </p>
<p>They make it possible for apps to react instantly to new data, from a user clicking a button to receiving messages from a web service.</p>
<h3 id="heading-operators">Operators</h3>
<p>Streams alone are useful, as they allow multiple Observers to subscribe to it for their updates. Things start to get more enjoyable when you want to manipulate a stream. Streams can be transformed and even combined, using operators.</p>
<p>RxJS itself for example contain hundreds of operators inspired by some well-known JavaScript's arrays’ methods like map, filter, reduce, etc.</p>
<p>Operators are simply functions that take an observable and return an observable with some operation applied to it. </p>
<p>Let's look at two essential operations: <strong>mapping and filtering</strong>. Take a look at the following animation:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/map-filter-stream-e0e9503b758fe89104ae60e0ecd48995.gif" alt="Image" width="600" height="400" loading="lazy">
<em>Figure 2: operators on an observable - <a target="_blank" href="https://reactive.how/filter">source</a></em></p>
<p>In <em>Figure 2</em> above, for the <code>map</code> operator, when the input observable emits a value, it is being processed by the <code>isEven</code> function and the resulting value is emitted as a value for the output observable. </p>
<p>For the <code>filter</code> operator, when the input stream emits a value, it is given to the same function, which emits a value for the output observable when it fulfills the condition. Otherwise, it is ignored. The input is an observable, and the operator returns another observable.</p>
<h2 id="heading-reactive-programming-in-javascripttypescript-and-beyond">Reactive Programming in JavaScript/TypeScript and Beyond</h2>
<p>In the world of JavaScript and TypeScript, particularly in the Node.js environment, streams and observables are crafted with both grace and effectiveness.</p>
<p>Node.js offers built-in support for streams, enabling powerful data handling capabilities for server-side applications. Also, libraries and frameworks built on top of the reactive programming paradigm, such as RxJS for JavaScript/TypeScript, provide developers with powerful tools to create reactive applications.</p>
<p>RxJS, for instance, is a library specifically designed for reactive programming in JavaScript/TypeScript. It provides a vast collection of operators to create, combine, and manipulate observables. With RxJS, developers can handle complex data flow scenarios with ease, thanks to its intuitive API and extensive operator set.</p>
<p>But reactive programming is not limited to JavaScript/TypeScript and Node.js. Many other programming languages have their own implementations of reactive programming paradigms and libraries.</p>
<p>For example, languages like Java have RxJava, Kotlin has RxKotlin, and Swift has RxSwift. These libraries offer similar functionalities to RxJS but are tailored to their respective language ecosystems.</p>
<p>Regardless of the programming language you're using, the principles of reactive programming remain applicable. Whether you're working in JavaScript, Java, Kotlin, Swift, or any other language, you can leverage reactive programming to build responsive, scalable, and maintainable applications. </p>
<p>The concepts of streams, observables, and operators transcend language barriers, providing developers with a powerful toolkit for handling asynchronous data flows and creating dynamic user experiences.</p>
<h2 id="heading-putting-it-all-together">Putting It All Together</h2>
<p>Imagine we're developing a feature for our bus station app that notifies users when their bus is approaching. Using RxJS, we can create an observable that represents the stream of bus arrival data. Each time a bus's status is updated—say, when it's 10 minutes away—the observable emits an event. Our app can subscribe to these events (observe them) and react by sending a notification to the user: "Your bus is on its way!"</p>
<p>This scenario showcases the power of reactive programming with streams and observables. Not only does it allow for real-time responsiveness, but it also simplifies the handling of asynchronous data flows, making our code cleaner and more intuitive.</p>
<p>This fundamental understanding of streams and observables is your first step into the world of reactive programming. As we move forward, remember the bus station's digital display and how it continuously updates. Our applications, much like an attentive traveler, has to be ready to respond to these updates as efficiently as possible. </p>
<p>With RxJS and the concepts of streams and observables, we're equipped to tackle these challenges head-on, creating applications that not only meet but exceed user expectations in terms of responsiveness and performance.</p>
<p>Engaging with these concepts is not just about understanding theory – it's about seeing the immense potential they unlock for developing dynamic, user-centric applications. As we dive deeper into practical examples, keep the bus station analogy in mind—it will help you grasp the more complex aspects of reactive programming in a relatable and straightforward way.</p>
<h2 id="heading-how-to-build-a-real-time-notification-system-with-nodejs">How to Build a Real-Time Notification System with Node.js</h2>
<p>In this section, we'll embark on a journey to create a real-time notification system using Node.js. Imagine a scenario where users of a web application need to receive instant updates on various events, such as new messages, notifications, or system alerts. </p>
<p>Our goal is to build a robust and efficient system that delivers these notifications seamlessly in real-time.</p>
<h3 id="heading-introduction-to-the-notification-system">Introduction to the Notification System</h3>
<p>Before diving into the technical implementation, let's envision how our real-time notification system will function. Users will interact with the system through a web interface, where they'll be able to subscribe to different types of notifications based on their preferences.</p>
<p>These notifications could include new messages in a chat room, updates on shared documents, or alerts for important system events. We will try to keep it very simple, since the goal is really getting started with the paradigm.</p>
<h3 id="heading-key-interactions-with-the-system">Key Interactions with the System</h3>
<ol>
<li><strong>User Subscription:</strong> Users will have the option to subscribe to specific types of notifications, tailoring their experience to their preferences and needs.</li>
<li><strong>Real-Time Delivery:</strong> Once subscribed, users will receive notifications instantly as they occur, ensuring timely communication and responsiveness.</li>
<li><strong>Actionable Notifications:</strong> Notifications will be actionable, allowing users to interact with them directly from the interface. For example, clicking on a notification might open the corresponding chat room or document.</li>
</ol>
<p>With this vision in mind, let's proceed to set up our Node.js project and lay the foundation for our real-time notification system. We'll start by configuring the project environment and installing the necessary dependencies, including RxJS, to power our reactive programming implementation.</p>
<h3 id="heading-project-setup-getting-started-with-nodejs-and-typescript">Project Setup: Getting Started with Node.js and TypeScript</h3>
<p>Before we can dive into implementing our real-time notification system, we need to set up our Node.js project environment. This involves configuring TypeScript for enhanced type checking and enabling RxJS to harness the power of reactive programming. </p>
<p>Let's walk through the steps to get our project up and running:</p>
<h4 id="heading-step-1-initialize-a-new-nodejs-project">Step #1 – Initialize a New Node.js Project</h4>
<p>Start by creating a new directory for your project and navigate into it:</p>
<pre><code class="lang-bash">$ mkdir real-time-notification-system
$ <span class="hljs-built_in">cd</span> real-time-notification-system
</code></pre>
<p>Next, initialize a new Node.js project using npm or yarn:</p>
<pre><code class="lang-bash">$ npm init -y
</code></pre>
<p>or</p>
<pre><code class="lang-bash">$ yarn init -y
</code></pre>
<h4 id="heading-step-2-install-dependencies">Step #2 – Install Dependencies</h4>
<p>Now, let's install the necessary dependencies for our project. We'll need TypeScript for type checking and compilation, as well as RxJS for reactive programming:</p>
<pre><code class="lang-bash">$ npm install typescript rxjs
</code></pre>
<p>or</p>
<pre><code class="lang-bash">$ yarn add typescript rxjs
</code></pre>
<h4 id="heading-step-3-configure-typescript">Step #3 – Configure TypeScript</h4>
<p>Create a <strong><code>tsconfig.json</code></strong> file in the root of your project to configure TypeScript:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"compilerOptions"</span>: {
    <span class="hljs-attr">"target"</span>: <span class="hljs-string">"ESNext"</span>,
    <span class="hljs-attr">"module"</span>: <span class="hljs-string">"CommonJS"</span>,
    <span class="hljs-attr">"outDir"</span>: <span class="hljs-string">"./dist"</span>,
    <span class="hljs-attr">"strict"</span>: <span class="hljs-literal">true</span>},
  <span class="hljs-attr">"include"</span>: [<span class="hljs-string">"src/**/*"</span>]
}
</code></pre>
<p>This configuration sets the compilation target to ESNext, enables strict type checking, and specifies the output directory for compiled TypeScript files.</p>
<h4 id="heading-step-4-set-up-project-structure">Step #4 – Set Up Project Structure</h4>
<p>Create a <strong><code>src</code></strong> directory to store your TypeScript source files:</p>
<pre><code class="lang-bash">$ mkdir src
</code></pre>
<p>Your project structure should now look like this:</p>
<pre><code class="lang-markdown">real-time-notification-system/
├── src/
├── node<span class="hljs-emphasis">_modules/
├── package.json
└── tsconfig.json</span>
</code></pre>
<p>Now, create a sample TypeScript file in the <strong><code>src</code></strong> directory to verify that TypeScript is working correctly:</p>
<pre><code class="lang-tsx">// src/index.ts
const message: string = 'Hello, world!';
console.log(message);
</code></pre>
<p>To run the file, you can either use Node, or any other JS runtime like Bun, using the following command:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># make sure bun is installed with bun -v command</span>
<span class="hljs-comment"># then run</span>
$ bun run src/index.ts
</code></pre>
<p>Make sure you get the “Hello, world” in the console before you proceed to the next step</p>
<h4 id="heading-step-5-compile-typescript">Step #5 – Compile TypeScript</h4>
<p>Compile your TypeScript code by running:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># then compile the project </span>
$ npx tsc
</code></pre>
<p>This will generate JavaScript files in the <strong><code>dist</code></strong> directory according to the configuration specified in <strong><code>tsconfig.json</code></strong>.</p>
<p>With our project set up and TypeScript configured, we're ready to start implementing the core features of our real-time notification system. </p>
<p>Let's move on to creating observables, applying operators, and handling real-time notifications in our application.</p>
<h3 id="heading-how-to-implement-the-core-features-building-a-real-time-notification-system">How to Implement the Core Features: Building a Real-Time Notification System</h3>
<p>Now, let's dive into implementing the core features of our real-time notification system. We'll create observables to represent different types of events, apply operators to filter and transform these event streams, and finally subscribe to these observables to handle real-time notifications effectively.</p>
<h4 id="heading-how-to-create-observables-modeling-event-streams">How to Create Observables – Modeling Event Streams</h4>
<p>In our notification system, we'll have various event streams representing different types of notifications. These could include new messages, user mentions, system alerts, and more.</p>
<p>Remember, everything can be observable, as this is very important when building reactive programs. Using RxJS (<a target="_blank" href="https://rxjs.dev/guide/overview">https://rxjs.dev/guide/overview</a>), you can manipulate any kind of stream in an observable way.</p>
<p>Before we get started, let’s see what I mean by that.</p>
<p>Given a button listening to a click event, JavaScript you can capture the event like this:</p>
<pre><code class="lang-tsx">&lt;button id='btn'&gt;Click Me&lt;/button&gt;

// in js file
const btn = document.getElementById("btn");
btn.addEventListener("click", (event) =&gt; {
  console.log('Button clicked');
});
</code></pre>
<p>While this works perfectly fine, it’s not reactive. What if you want to combine the click event with another event, such as a timer or an HTTP request? This is where reactive programming comes in.</p>
<p>With reactive programming, you can treat all of these events as streams of data and combine them in a declarative and composable way. </p>
<p>Imagine a scenario where we need to print a message when two click events that happen in within a 5 seconds interval, or print a message with an array of positions the mouse occupied on the browser between two click events. Or to print a message when the user clicks on the button and the enter keyword within a 2 seconds interval. </p>
<p>All these scenarios are possible with usual imperative programming but may require more tricky code, and thinking reactively may become a must. </p>
<p>Let's try to build the first scenario in a usual way, then we 'll see how reactive programming can help us to make it more readable and maintainable.</p>
<pre><code class="lang-tsx">const btn = document.getElementById("btn");

let clickCount = 0;
let lastClickTime = 0;

btn.addEventListener("click", (event) =&gt; {
  clickCount++;
  if (clickCount === 1) {
    lastClickTime = new Date().getTime();
  } else if (clickCount === 2) {
    if (new Date().getTime() - lastClickTime &lt; 5000) {
      console.log('Two clicks in less than 5 seconds');
    }
    clickCount = 0;
  }
});
</code></pre>
<p>Now let's see how we can achieve the same result using a reactive programming approach with <code>rxjs</code> in the following code snippet:</p>
<pre><code class="lang-tsx">import { fromEvent } from 'rxjs';
import { buffer, debounceTime, filter } from 'rxjs/operators';

const btn = document.getElementById("btn");
const btnClick$ = fromEvent(btn, 'click');
btnClick$.pipe(
  buffer(btnClick$.pipe(debounceTime(5000))),
  filter(clickArray =&gt; clickArray.length === 2)
).subscribe(() =&gt; {
  console.log('Two clicks in less than 5 seconds');
});
</code></pre>
<p>In the code above, we used the <code>fromEvent</code> function from <code>rxjs</code> (<a target="_blank" href="https://rxjs.dev/api/index/function/fromEventPattern">https://rxjs.dev/api/index/function/fromEventPattern</a>) to create an observable from the click event on the button. We then used the <code>buffer</code> and <code>debounceTime</code> operators to buffer the click events and filter out the ones that occurred within 5 seconds. </p>
<p>This allowed us to easily handle the scenario of two clicks occurring within 5 seconds, all in a declarative and composable way. The <code>$</code> symbol is a common notation to identify a stream, while fully optional, you may need to use it when working on a collaborative project, since it’s very common to see it.</p>
<p>As you can see, the reactive programming approach is much more declarative and composable, maybe not intuitive when using it the first time, but making it easier to understand and maintain. This is a very basic example, but it shows the power of reactive programming when dealing with complex event combinations. </p>
<p>Reactive programming allows you to treat all events as streams of data and manipulate them in a declarative and composable way, making it easier to handle complex scenarios and maintainable code.</p>
<p><strong>⚒️ Hands on exercise:</strong> To get more familiar, try to build the second scenario using both ways and see how you can do some complex event management using very few lines of code</p>
<p>Now that you have an idea of how you can turn almost anything to an observable, let’s get our hands dirty and code our sample notification system. This will be a very basic example, the goal is to show how you can benefit from reactive programming when dealing with a complex combination of events or a stream of intensive data in your future applications.</p>
<p>Let's start by creating observables to represent these event streams:</p>
<pre><code class="lang-tsx">// src/observables.ts
import { Observable } from 'rxjs';

// Observable for new messages
export const newMessage$ = new Observable&lt;string&gt;((subscriber) =&gt; {
  // Simulate receiving new messages
  setInterval(() =&gt; {
    subscriber.next('New message received');
  }, 3000);
});

// Observable for user mentions
export const userMentions$ = new Observable&lt;string&gt;((subscriber) =&gt; {
  // Simulate user mentions
  setInterval(() =&gt; {
    subscriber.next('You were mentioned in a message');
  }, 5000);
});

// Observable for system alerts
export const systemAlerts$ = new Observable&lt;string&gt;((subscriber) =&gt; {
  // Simulate system alerts
  setInterval(() =&gt; {
    subscriber.next('System alert: Server down');
  }, 10000);
});
</code></pre>
<p>In the code above, we have created three observables using the <code>Observable</code> class from <code>rxjs</code> (<a target="_blank" href="https://rxjs.dev/guide/observable">https://rxjs.dev/guide/observable</a>): <code>newMessage$</code>, <code>userMentions$</code>, and <code>systemAlerts$</code>. </p>
<p>Each of these observables emit a new value at different intervals. The <code>newMessage$</code> observable emits a new message every 3 seconds, the <code>userMentions$</code> observable emits a new message every 5 seconds, and the <code>systemAlerts$</code> observable emits a new message every 10 seconds. Now that we have our observables set up, we can subscribe to them and handle the emitted values in our application.</p>
<h4 id="heading-how-to-apply-operators-transforming-event-streams">How to Apply Operators – Transforming Event Streams</h4>
<p>Next, let's apply operators to filter and transform our event streams to generate actionable notifications. We'll use operators like <strong><code>filter</code></strong>, <strong><code>map</code></strong>, and <strong><code>merge</code></strong> to process incoming data streams and generate meaningful notifications:</p>
<pre><code class="lang-tsx">// src/operators.ts
import { newMessage$, userMentions$, systemAlerts$ } from './observables';
import { merge, map, filter } from 'rxjs';

// Combine multiple event streams into one
export const combinedNotifications$ = merge(
  newMessage$.pipe(map(message =&gt; `New message: ${message}`)),
  userMentions$.pipe(map(mention =&gt; `You were mentioned: ${mention}`)),
  systemAlerts$.pipe(map(alert =&gt; `System alert: ${alert}`))
);

// Filter notifications based on user preferences
export const filteredNotifications$ = combinedNotifications$.pipe(
  filter(notification =&gt; notification.startsWith('New message'))
);
</code></pre>
<p>In the code above, we have created three observables: <code>newMessage$</code>, <code>userMentions$</code>, and <code>systemAlerts$</code>. Each of these observables emit a new value at different intervals. The <code>newMessage$</code> observable emits a new message every 3 seconds, the <code>userMentions$</code> observable emits a new message every 5 seconds, and the <code>systemAlerts$</code> observable emits a new message every 10 seconds.</p>
<h4 id="heading-how-to-handle-real-time-notifications-subscribing-to-observables">How to Handle Real-Time Notifications – Subscribing to Observables</h4>
<p>Finally, let's subscribe to our observables to handle real-time notifications in our application. We'll subscribe to the combined notifications stream and display notifications to the user in a simulated client interface:</p>
<pre><code class="lang-tsx">// src/index.ts
import { combinedNotifications$, filteredNotifications$ } from './operators';

// Subscribe to combined notifications and display them in the UI
combinedNotifications$.subscribe(notification =&gt; {
  // Simulate displaying notifications in the UI
  console.log('Displaying notification:', notification);
});

// Subscribe to filtered notifications based on user preferences
filteredNotifications$.subscribe(notification =&gt; {
  // Simulate displaying filtered notifications in the UI
  console.log('Displaying filtered notification:', notification);
});
</code></pre>
<p>In the code snippet above, we have created two observables: <code>combinedNotifications$</code> and <code>filteredNotifications$</code>. The first one combines multiple event streams into one using the merge operator. The second one filters notifications based on user preferences using the filter operator. We then subscribe to these observables and display the notifications in the UI.</p>
<p>Let’s test things out again using <code>bun</code>:</p>
<pre><code class="lang-bash">$ bun run src/index.ts
</code></pre>
<p>You should have the following output:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/03/Screenshot-2024-03-14-at-16.02.15.png" alt="Image" width="600" height="400" loading="lazy">
<em>Figure 3: terminal output when running the project</em></p>
<p>As you can see, the notifications are being displayed in the UI as expected, and they keep coming in as new events are emitted, untill the program is stopped. </p>
<p>Another way to stop getting notifications is to unsubscribe from the observables, adding a condition that will execute the following block:</p>
<pre><code class="lang-tsx">combinedNotifications$.unsubscribe();
</code></pre>
<p>⚒️  <strong>Over to you:</strong><br>Feel free to interact with the code and explore how observables and operators work together to handle real-time notifications effectively. Experiment with different event streams and filters to tailor the notifications to your preferences, making sure you get to use as more RxJS operators as possible. As you code along, consider real-world use cases and how this notification system can be applied to various applications.</p>
<p>You can find the full source code for this article at the following GitHub repo: <a target="_blank" href="https://github.com/pacyL2K19/rx-programming-real-time-sample">https://github.com/pacyL2K19/rx-programming-real-time-sample</a>. Kindly leave a star if you find it helpful.</p>
<h2 id="heading-best-practices-and-common-pitfalls">Best Practices and Common Pitfalls</h2>
<p>Reactive programming is a powerful paradigm, but it comes with its own set of best practices and potential pitfalls. </p>
<p>Let's explore some key considerations when working with reactive programming in real-world applications:</p>
<h3 id="heading-best-practices">Best Practices:</h3>
<p>Here are are some of the best practices you need to follow when building application in a reactive way:</p>
<ul>
<li><strong>Declarative and Composable:</strong> Leverage the declarative and composable nature of reactive programming to handle complex event streams and data flows. Use operators to transform and combine observables in a clear and maintainable way.</li>
<li><strong>Error Handling:</strong> Implement robust error handling mechanisms to manage exceptions or failures in your event streams. Use operators like <code>catchError</code> (<a target="_blank" href="https://rxjs.dev/api/operators/catchError">https://rxjs.dev/api/operators/catchError</a>) or <code>retryWhen</code> (<a target="_blank" href="https://rxjs.dev/api/index/function/retryWhen">https://rxjs.dev/api/index/function/retryWhen</a>) to handle errors gracefully.</li>
<li><strong>Memory Management:</strong> Be mindful of memory management when working with observables. Unsubscribe from observables when they are no longer needed to avoid memory leaks and unnecessary resource consumption.</li>
<li><strong>Testing:</strong> Write comprehensive unit tests for your observables and operators to ensure they behave as expected. Use testing libraries like <code>Jest</code> or <code>Mocha</code> to test your reactive code.</li>
</ul>
<h3 id="heading-common-pitfalls">Common Pitfalls:</h3>
<ul>
<li><strong>Overusing Operators:</strong> Avoid overusing operators, especially in complex event streams. While managing complex data/event streams can lead to using more than one operator, an overuse of operators can lead to code that is difficult to understand and maintain, always seek for an optimal use of operators.</li>
<li><strong>Complexity:</strong> Be cautious of overly complex event streams and data flows. Strive to keep your reactive codebase simple and intuitive to avoid confusion and bugs.</li>
<li><strong>Performance:</strong> Keep an eye on performance when working with reactive programming. Intensive data processing and complex event combinations can impact performance if not managed carefully, especially knowing when to subscribe and when to unsubscribe from observables, making sure the resources are used optimally.</li>
</ul>
<p>By following best practices and being aware of common pitfalls, you can harness the full potential of reactive programming while ensuring the maintainability and performance of your applications.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Reactive programming is a transformative paradigm that empowers developers to build responsive, scalable, and efficient applications. By leveraging the principles of streams, observables, and operators, developers can handle complex data flows and asynchronous operations with ease. </p>
<p>Whether you're building real-time dashboards, IoT applications, or financial trading platforms, reactive programming provides a versatile and powerful toolkit for handling dynamic data streams. As you continue your journey with reactive programming, remember the core concepts of streams and observables.</p>
<p>Embrace the declarative and composable nature of reactive programming, and explore the vast array of operators available to transform and combine observables. By doing so, you'll unlock the full potential of reactive programming and create applications that meet the demands of modern software development.</p>
<h3 id="heading-resources">Resources</h3>
<ul>
<li><a target="_blank" href="https://lup.lub.lu.se/luur/download?func=downloadFile&amp;recordOId=8932146&amp;fileOId=8932147">Reactive programming and its effect on performance and the development process</a> By Gustav Hochbergs</li>
<li><a target="_blank" href="https://gist.github.com/staltz/868e7e9bc2a7b8c1f754">The introduction to Reactive Programming you've been missing</a> By André Staltz</li>
<li><a target="_blank" href="https://devm.io/java/the-fight-for-performance-157515">The fight for performance</a> By Arne Limburg</li>
<li><a target="_blank" href="https://developer.ibm.com/series/learning-path-introduction-to-reactive-systems/">Introduction to reactive programming</a> by IBM</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build Reusable React Components ]]>
                </title>
                <description>
                    <![CDATA[ What are reusable React components? You can think of them as building blocks. They are independent pieces of code that can be reused throughout your website to save you time and effort. They can be anything from simple buttons to complex forms. Why U... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-reusable-react-components/</link>
                <guid isPermaLink="false">66bfa1c9a1fd8cc5bc645a0d</guid>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ components ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Programming with Shahan ]]>
                </dc:creator>
                <pubDate>Wed, 28 Feb 2024 19:05:07 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/02/Purple-Blue-Modern-Gradient-New-Blog-Post-Emoji-Twitter-Post--1--1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>What are reusable React components? You can think of them as building blocks. They are independent pieces of code that can be reused throughout your website to save you time and effort.</p>
<p>They can be anything from simple buttons to complex forms.</p>
<h2 id="heading-why-use-reusable-components">Why Use Reusable Components?</h2>
<p>As your website grows, you can easily add new features by combining existing components. This makes your code more scalable and adaptable.</p>
<p>You can use your reusable code in future projects without writing it again from scratch.</p>
<h2 id="heading-how-to-make-reusable-react-components">🏭 How to Make Reusable React Components</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/02/Designer--10-_LE_auto_x2_colored.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Illustration credit: <a target="_blank" href="https://www.youtube.com/programmingwithshahan">Shahan</a></em></p>
<p>Here are the two most important things to keep in mind when creating reusable React components:</p>
<h2 id="heading-1-avoid-side-effects">1. 🩼Avoid Side Effects</h2>
<p>Don't put logic that interacts with external data (like making API calls) directly inside a reusable component. Instead, pass this logic as <code>props</code> to the component.</p>
<p>For example, if a button does more than just looking pretty, like fetching data from the internet, it might not be reusable.</p>
<p>This is a reusable button component. But it lacks best practices. I will show you why in the example section.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// This is a reusable button component (bad practice!)</span>
<span class="hljs-keyword">const</span> Button = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>&gt;</span> Click Me <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-2-use-props">2. 🗃️ Use Props</h2>
<p>Props are arguments you pass to a component to customize its behavior and appearance. This allows you to use the same component for different purposes.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// This is a button component that can change its color</span>
<span class="hljs-keyword">const</span> Button = <span class="hljs-function">(<span class="hljs-params">{ color }</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">style</span>=<span class="hljs-string">{{</span> <span class="hljs-attr">backgroundColor:</span> <span class="hljs-attr">color</span> }}&gt;</span> Click Here <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  );
}
</code></pre>
<p>This is still a bad practice because you have a fixed label called "Click Here". If you want to change the text on your button to, let's say: "Sign Up", then you would have to go back to the button component and make that change.</p>
<p>That means every time you want to use a different text, we'd have to go back and edit the code. In other words, it's no longer reusable.</p>
<p><strong>💪 Challenge:</strong> So what's the solution?</p>
<p>You already have the answer. But if you don't, I am going to show you in the example section.</p>
<p><strong>🌴 Hint:</strong> Think about how you might want to use the component in different situations and design it to be flexible and adaptable.</p>
<h2 id="heading-examples-of-reusable-react-components">🍃Examples of Reusable React Components</h2>
<p>Here are some common examples of reusable React components, along with some code examples to get you started:</p>
<h3 id="heading-buttons">Buttons</h3>
<p>Basic buttons with different styles and functionalities.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// Button component</span>
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> Button = <span class="hljs-function">(<span class="hljs-params">{ color, label, onClick }</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>
      <span class="hljs-attr">className</span>=<span class="hljs-string">{</span>`<span class="hljs-attr">padding-2</span> <span class="hljs-attr">shadow-none</span> <span class="hljs-attr">hover:shadow</span> <span class="hljs-attr">background-light-</span>${<span class="hljs-attr">color</span>} <span class="hljs-attr">hover:background-dark-</span>${<span class="hljs-attr">color</span>}`}
      <span class="hljs-attr">onClick</span>=<span class="hljs-string">{onClick}</span>
    &gt;</span>
      {label}
    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Button;

<span class="hljs-comment">// Using the Button component</span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">color</span>=<span class="hljs-string">"blue"</span> <span class="hljs-attr">label</span>=<span class="hljs-string">"Click Here"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> console.log("Button clicked!")} /&gt;</span>
</code></pre>
<p>As you can see, I did not write "Click Here" in the <code>button</code> component. I want to make my button reusable, and thus it doesn't know anything about custom styles or texts.</p>
<p>So, I passed them as props (i.e., color, label, and onClick) to change them in the future without touching the original button components. Hope that makes it clear.</p>
<p><strong>🪜Solution:</strong> You need to pass each functionality as <code>props</code> in the reusable component.</p>
<h3 id="heading-navbars">Navbars</h3>
<p>Navigation bars that provide consistent navigation across your website.</p>
<pre><code class="lang-jsx"><span class="hljs-comment">// Navbar component</span>
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-keyword">const</span> Navbar = <span class="hljs-function">(<span class="hljs-params">{ isLoggedIn }</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"navbar"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"navbar-container"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"navbar-logo"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">{logo}</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"logo"</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"navbar-links"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span>&gt;</span>Home<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/about"</span>&gt;</span>About<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/contact"</span>&gt;</span>Contact<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
          {isLoggedIn ? (
            <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/profile"</span>&gt;</span>Profile<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
          ) : (
            <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/login"</span>&gt;</span>Login<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
          )}
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> Navbar;

<span class="hljs-comment">// Using the Navbar component</span>
<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Navbar</span> <span class="hljs-attr">isLoggedIn</span>=<span class="hljs-string">{true}</span> /&gt;</span></span>
</code></pre>
<p>As you can see, I passed  <code>&lt;Navbar isLoggedIn={true} /&gt;</code></p>
<p>This line utilizes the <code>Navbar</code> component and passes the <code>isLoggedIn</code> prop with a value of <code>true</code>, indicating the user is logged in. This will display the "Profile" link and hide the "Login" link. </p>
<p>Similar to the button component, the <code>Navbar</code> component is reusable and accepts props to customize its behavior. Perfect!</p>
<h3 id="heading-why-api-calls-in-a-button-component-is-a-bad-practice">Why API Calls in a Button Component is a Bad Practice</h3>
<p>Now, you understand everything about reusable components in React.</p>
<p>Let's dig deeper by solving a complex problem.</p>
<p>Consider the scenario where you have a button that does an API call. The code for the button component can be the following:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>; 
<span class="hljs-keyword">import</span> doAPICall <span class="hljs-keyword">from</span> <span class="hljs-string">"../api"</span>

<span class="hljs-keyword">const</span> SaveButton  = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>
      <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> {
        doAPICall();
      }}
    &gt;
      Save
    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> SaveButton
</code></pre>
<p>It is quite clear that you can’t reuse the above button in multiple places as this button component contains a side-effect (<code>doAPICall()</code>) inside it.</p>
<p>You can make this component reusable. First, you'll have to extract out the side-effect and pass that as a prop to the button component like this:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span>  {
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">doAPICall</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Does an API call to save the current state of the app.</span>
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">SaveButton</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{doAPICall}/</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre>
<p>The button component should look like this:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> SaveButton  = <span class="hljs-function">(<span class="hljs-params">{
  onClick
}</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>
      <span class="hljs-attr">onClick</span>=<span class="hljs-string">{onClick}</span>
    &gt;</span>
      Save
    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  );
}
</code></pre>
<p>As you can see, the above button can now be reused anywhere you want to save data with the click of a button. The button can now be used like this in multiple places:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span>  {
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">saveUser</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Does an API call to save the user.</span>
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">saveProject</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Does an API call to save the project.</span>
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">SaveButton</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{saveUser}/</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">SaveButton</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{saveProject}/</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre>
<p>You can also make the button component more reusable by using a prop to control the label:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span>  {
  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">saveUser</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Does an API call to save the user.</span>
  }

  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">saveProject</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-comment">// Does an API call to save the project.</span>
  }

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">SaveButton</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{saveUser}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">"Save user"</span>  /&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">SaveButton</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{saveProject}</span> <span class="hljs-attr">label</span>=<span class="hljs-string">"Save project"</span> /&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  )
}
</code></pre>
<p>The button component should look like this:</p>
<pre><code class="lang-jsx"><span class="hljs-keyword">const</span> SaveButton  = <span class="hljs-function">(<span class="hljs-params">{
  onClick,
  label
}</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span>
      <span class="hljs-attr">onClick</span>=<span class="hljs-string">{onClick}</span>
    &gt;</span>
      {label}
    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-conclusion">👏Conclusion</h2>
<p>Congratulations! You've successfully learned how to build reusable React components. </p>
<p>Remember, reusable components are the building blocks of robust React development. By practicing reusable components, you can build cleaner, more efficient, and more maintainable React applications. </p>
<p>The more you practice, the better you'll become at identifying opportunities to use them in your projects!</p>
<p><strong>Read More:</strong> <a target="_blank" href="https://dev.to/codewithshahan/the-future-of-frontend-development-1amd">The Future of Frontend Development</a></p>
<p>Thank you for taking the time to read this article. Until next time.. Keep learning and you can follow me on <strong><a target="_blank" href="https://twitter.com/shahancd">𝕏</a></strong>  for latest updates on programming and productivity. </p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ JS DOM Manipulation Best Practices – with Examples ]]>
                </title>
                <description>
                    <![CDATA[ In JavaScript, you can manipulate the content of a web page using the Document Object Model (DOM). But how do you write code that is readable, easy to maintain, and not prone to performance issues? That's what we'll cover in this article. I'll discus... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/dom-manipulation-best-practices/</link>
                <guid isPermaLink="false">66d45dd6aad1510d0766b5e9</guid>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Document Object Model ]]>
                    </category>
                
                    <category>
                        <![CDATA[ DOM ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Benjamin Semah ]]>
                </dc:creator>
                <pubDate>Fri, 12 Jan 2024 17:41:27 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/freecodecamp-javascript-benjamin-semah.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In JavaScript, you can manipulate the content of a web page using the Document Object Model (DOM). But how do you write code that is readable, easy to maintain, and not prone to performance issues?</p>
<p>That's what we'll cover in this article. I'll discuss some important best practices so that you can manipulate the DOM with confidence.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#">Introduction</a></p>
</li>
<li><p><a class="post-section-overview" href="#user-the-domcontentloaded-event">Use the DOMContentLoaded Event</a></p>
</li>
<li><p><a class="post-section-overview" href="#cache-selected-elements">Cache Selected Elements</a></p>
</li>
<li><p><a class="post-section-overview" href="#query-parent-elements-instead-of-document">Query Parent Instead of Document</a></p>
</li>
<li><p><a class="post-section-overview" href="#use-css-classes-to-style-elements">Use CSS Classes to Style Elements</a></p>
</li>
<li><p><a class="post-section-overview" href="#use-innerhtml-with-caution">Use innerHTML With Caution</a></p>
</li>
<li><p><a class="post-section-overview" href="#write-readable-event-listeners">Write Readable Event Listeners</a></p>
</li>
<li><p><a class="post-section-overview" href="#use-event-delegation-to-handle-dom-events">Use Event Delegation to Handle DOM Events</a></p>
</li>
<li><p><a class="post-section-overview" href="#batch-dom-updates-with-fragment">Batch DOM Updates With Fragment</a></p>
</li>
<li><p><a class="post-section-overview" href="#use-the-stoppropagation-method">Use the stopPropagation Method</a></p>
</li>
<li><p><a class="post-section-overview" href="#test-your-dom-manipulation-code">Test your DOM Manipulation code</a></p>
</li>
<li><p><a class="post-section-overview" href="#conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-user-the-domcontentloaded-event">User the <code>DOMContentLoaded</code> Event</h2>
<p>The <code>DOMContentLoaded</code> event is fired when the HTML document is fully loaded. Using this event ensures that your DOM manipulation code runs only after the document is fully loaded.</p>
<p>To use the <code>DOMContentLoaded</code>, add an event listener to the document and listen for the <code>DOMContentLoaded</code> event. This helps prevent any issues that may come up when you try to manipulate elements that are yet to be rendered.</p>
<p>Example:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">document</span>.addEventListener(<span class="hljs-string">'DOMContentLoaded'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// Your DOM manipulation code goes here...</span>
})
</code></pre>
<h2 id="heading-cache-selected-elements">Cache Selected Elements</h2>
<p>When you have frequently used elements, querying the DOM for the same element anytime over and over is inefficient. It's better to query the DOM once and store the result in variables.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> cachedElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'exampleId'</span>)
</code></pre>
<p>This way you can reference the variables anytime you want to use them. This helps improve performance as it reduces unnecessary work.</p>
<h2 id="heading-query-parent-elements-instead-of-document">Query Parent Elements Instead of Document</h2>
<p>When you cache an element, you can also query it to select any of its descendants. This can help improve performance because it limits the scope of the query and reduces the number of times the entire document is queried.</p>
<p>Example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"parent"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"child"</span>&gt;</span>Example paragraph<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> parentElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'parent'</span>)

<span class="hljs-comment">// Options 1: Querying entire document ❌</span>
<span class="hljs-keyword">const</span> childFromDocument = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'child'</span>) 

<span class="hljs-comment">// Options 2: Query the parent element ✅</span>
<span class="hljs-keyword">const</span> childFromParent = parentElement.querySelector(<span class="hljs-string">'#child'</span>)
</code></pre>
<p>In the example above is a simple markup containing a <code>#parent</code> div and <code>.child</code> paragraph. Then there are two options for selecting the child element.</p>
<p>Technically, both options are correct and will select the same element. But the difference is in the scope of the query.</p>
<p>Example 1 queries (or searches) the entire document to find and select the child. This is less performant and not even necessary because the parent of the element you intend to select is already cached.</p>
<p>Example 2 narrows the scope of the query (or search) by querying only the parent element and not the whole document. That's why it's preferred because it's more performant – especially when the document is large.</p>
<p>Also, note that the method used for querying the parent is <code>querySelector</code>. Using <code>getElementById</code> to query the parent won't work and will result in an error.</p>
<h2 id="heading-use-css-classes-to-style-elements">Use CSS Classes to Style Elements</h2>
<p>It's best to use CSS classes to style elements instead of using inline styles. Classes are easy to maintain compared to inline styles which can be hard to manage.</p>
<p>The <code>classList</code> property has useful properties like add, remove, toggle, and others that makes it easy to modify styles.</p>
<p>Example:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.styledClass</span> {
  <span class="hljs-attribute">color</span>: red;
}
</code></pre>
<pre><code class="lang-javascript">element.classList.add(<span class="hljs-string">'styledClass'</span>)
</code></pre>
<p>This example uses the <code>.add</code> property of <code>classList</code> to add the <code>styledClass</code> to the element. Assuming you wanted to remove the class from the element, you can easily do so using the <code>.remove</code> property in place of add.</p>
<h2 id="heading-use-innerhtml-with-caution">Use <code>innerHTML</code> with Caution</h2>
<p>The <code>innerHTML</code> property reads and parses HTML markup that you pass to it. This means it can read and run code in a script tag passed to it. And this can pose a security risk to your application.</p>
<p>Where possible, use the <code>innerText</code> or <code>textContent</code> property to render strings. But if you need to use <code>innerHTML</code>, be sure you're using it to insert content from trusted sources. Or sanitize and validate the provided content with a library like DOMPurify.</p>
<p>You can read <a target="_blank" href="https://www.freecodecamp.org/news/innerhtml-vs-innertext-vs-textcontent/#what-is-the-innerhtml-property">this freeCodeCamp article</a> to learn more about <code>innerHTML</code>.</p>
<h2 id="heading-write-readable-event-listeners">Write Readable Event Listeners</h2>
<p>Often you will pass two arguments to event listeners. The first is the event you're listening to and the second is the event handler (the function that fires when the event occurs).</p>
<p>To make your code easy to read and maintain, you can define the event handler function outside of the event listener. Then you can call it within the even listener, like in example 1 below:</p>
<pre><code class="lang-javascript">Example <span class="hljs-number">1</span> ✅

MyElement.addEventListener(<span class="hljs-string">'click'</span>, handleClick) 

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params"></span>) </span>{ 
    <span class="hljs-comment">// your logic goes here.. </span>
} 

<span class="hljs-comment">// Example 2 ❌ </span>

myElement.addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ 
    <span class="hljs-comment">// your logic goes here... </span>
})
</code></pre>
<p>Both are technically correct and will do the same thing. But example 1 is preferred because it's easier to read. Also, you can reuse the <code>handleClick</code> function if you need to. This helps you observe the DRY (Don't Repeat Yourself) principle.</p>
<h2 id="heading-use-event-delegation-to-handle-dom-events">Use Event Delegation to Handle DOM Events</h2>
<p>Event delegation is when you attach an event listener on a parent element to listen to events on its descendants. With this technique, you can reduce the number of event listeners to include in your code.</p>
<p>For example, assume you have five buttons inside a parent div:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"parent"</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn-1"</span>&gt;</span>1st Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn-2"</span>&gt;</span>2nd Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn-3"</span>&gt;</span>3rd Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn-4"</span>&gt;</span>4th Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"btn-5"</span>&gt;</span>5th Button<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>You can add an event listener to each of the five buttons to listen to a click. Or using event delegation, you can a single event on only the parent div:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> parentElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'parent'</span>) 

parentElement.addEventListener(<span class="hljs-string">'click'</span>, handleClick) 

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleClick</span>(<span class="hljs-params">event</span>) </span>{ 
  alert(event.target.id) 
}
</code></pre>
<p>In this example, the event to delegated to the parent element. And we're using <code>event.target.id</code> to get the actual button the user clicked. If you are curious, you can <a target="_blank" href="https://stackblitz.com/edit/js-r3qjyd?file=index.html,index.js">run the code on Stackblitz</a> to see how it works.</p>
<p>Event delegation help saves time improve performance. Imagine how this technique can come in handy when dealing with a large amount of dynamic content.</p>
<h2 id="heading-batch-dom-updates-with-fragment">Batch DOM Updates With Fragment</h2>
<p>Frequent updates to the DOM can affect the performance of your application. Try to reduce the number of updates where possible.</p>
<p>A useful feature you can use to batch updates is the <code>.createDocumentFragment</code> property. It allows you to group multiple updates before inserting them into the document. This reduces reflows and makes your code more effecient.</p>
<p>Example without Fragment:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> container = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'container'</span>)

<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">1000</span>; i++) { 
    <span class="hljs-keyword">const</span> listItem = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'li'</span>)
    listItem.textContent = <span class="hljs-string">`Item <span class="hljs-subst">${i}</span>`</span>
    container.appendChild(listItem) 
}
</code></pre>
<p>This code updates with each iteration of the loop. That means the DOM will be update 1,000 times. There is a more efficient way of doing this with the code below that uses fragment.</p>
<p>Example with fragment:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> container = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'container'</span>) 
<span class="hljs-keyword">const</span> fragment = <span class="hljs-built_in">document</span>.createDocumentFragment()

<span class="hljs-comment">// Add multiple list items to the fragment </span>
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; <span class="hljs-number">1000</span>; i++) { 
    <span class="hljs-keyword">const</span> listItem = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'li'</span>) 
    listItem.textContent = <span class="hljs-string">`Item <span class="hljs-subst">${i}</span>`</span> 
    fragment.appendChild(listItem)
} 

container.appendChild(fragment)
</code></pre>
<p>The code above appends the <code>listItem</code> to the <code>fragment</code> with each iteration of the loop. It only appends the child to the <code>container</code> element after the loop is done running. This means the DOM is updated only once instead of 1,000 times like before.</p>
<h2 id="heading-use-the-stoppropagation-method">Use the <code>stopPropagation</code> Method</h2>
<p>The <code>stopPropagation</code> method controls the flow of events in the DOM. By default, when an event occurs on an element, it bubbles (propagates) through its ancestors.</p>
<p>This event propagating behaviour can sometimes lead to unintended results. The <code>stopPropagation</code> method provides a way to stop the event from propagating to the parent and other ancestors.</p>
<p>Let's take a situation where you have a button inside a parent div. And you want to handle a click event on the button without registering the click on the div:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"container"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"button"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> containerDiv = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'container'</span>)
<span class="hljs-keyword">const</span> buttonElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'button'</span>)

containerDiv.addEventListener(<span class="hljs-string">'click'</span>, handleDivClick)
buttonElement.addEventListener(<span class="hljs-string">'click'</span>, handleBtnClick)

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleDivClick</span>(<span class="hljs-params"></span>) </span>{ 
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Div clicked'</span>)
} 

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handleBtnClick</span>(<span class="hljs-params">event</span>) </span>{ 
    event.stopPropagation()
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Button clicked'</span>)
}
</code></pre>
<p>Without using the <code>stopPropagation</code> method, a click event on the button will also trigger a click event on the parent div. This means both event handlers will run.</p>
<p>But the <code>event.stopPropagation()</code> line in the code will prevent the <code>handleDivClick</code> function from running when a user clicks the button.</p>
<p>You can <a target="_blank" href="https://stackblitz.com/edit/js-wjmnd5?file=index.html,index.js">run the code on Stackblitz</a> to see how it works. Comment out the line with the <code>stopPropagation</code> method and see the difference.</p>
<h2 id="heading-test-your-dom-manipulation-code">Test Your DOM Manipulation Code</h2>
<p>When you write tests, you create scenarios that mimic user interactions or application states. You also verify that your application gives you the expected outcomes.</p>
<p>Testing your DOM manipulation code is a best practice because it will make your code reliable and easy to maintain. It also gives you confidence that your code behaves as expected, even as it evolves over time when you make changes and add features.</p>
<p>You can use testing frameworks and libraries available for JavaScript, such as Jest, Mocha, Jasmine, and others to automate testing your apps.</p>
<p>The following example uses the Jest framework to test DOM Manipulation code for adding a class to an element.</p>
<pre><code class="lang-javascript">test(<span class="hljs-string">'Adding a highlight class changes text color to red'</span>, <span class="hljs-function">() =&gt;</span> {
    myElement.classList.add(<span class="hljs-string">'highlight'</span>);
    expect(getComputedStyle(myElement).color).toBe(<span class="hljs-string">'red'</span>);
});
</code></pre>
<p>Adding the <code>highlight</code> class is expected to change the text color to red. If the test passes, it means your DOM manipulation code works as expected. If not, you will need to figure out what figure out what's wrong and fix the issue.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article you've learned ten best practices to keep in mind when working with the DOM. Some of them are general while others are situation specific. By using these best practices in your workflow, you will be building your web applications with a code base that is easy to maintain.</p>
<p>If you want to dive deep into DOM manipulation, <a target="_blank" href="https://www.freecodecamp.org/news/the-javascript-dom-manipulation-handbook/">I wrote a whole handbook</a> that covers the subject in depth.</p>
<p>Thanks for reading. And happy coding! For more in-depth tutorials, feel free to <a target="_blank" href="https://www.youtube.com/@DevAfterHours">subscribe to my YouTube channel</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Web Accessibility Best Practices – How to Ensure Everyone Can Use Your Website ]]>
                </title>
                <description>
                    <![CDATA[ In the dynamic world of web development, creating websites that are accessible to all users, including those with disabilities, is not just a best practice – it's a necessity.  Web accessibility ensures that everyone, regardless of their abilities, c... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/web-accessibility-best-practices/</link>
                <guid isPermaLink="false">66bae6bcac70cebcb65690af</guid>
                
                    <category>
                        <![CDATA[ a11y ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Sudheer Kumar Reddy Gowrigari ]]>
                </dc:creator>
                <pubDate>Sun, 17 Dec 2023 21:27:27 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/12/accessibility-2-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In the dynamic world of web development, creating websites that are accessible to all users, including those with disabilities, is not just a best practice – it's a necessity. </p>
<p>Web accessibility ensures that everyone, regardless of their abilities, can perceive, understand, navigate, and interact with the web. This inclusivity not only broadens your audience but also reflects social responsibility and compliance with legal standards.</p>
<h3 id="heading-heres-what-well-cover">Here's what we'll cover:</h3>
<ol>
<li><a class="post-section-overview" href="#heading-what-is-web-accessibility">What is Web Accessibility?</a></li>
<li><a class="post-section-overview" href="#heading-best-practices-for-web-accessibility">Best Practices for Web Accessibility</a><br>– <a class="post-section-overview" href="#heading-use-semantic-html">Use semantic HTML</a><br>– <a class="post-section-overview" href="#heading-use-sufficient-contrast">Use sufficient contrast</a><br>– <a class="post-section-overview" href="#heading-make-all-functionality-keyboard-accessible">Make all functionality keyboard accessible</a><br>– <a class="post-section-overview" href="#heading-provide-alt-text-for-images">Provide alt text for images</a><br>– <a class="post-section-overview" href="#heading-use-aria-accessible-rich-internet-applications-roles-when-necessary">Use ARIA roles when necessary</a><br>– <a class="post-section-overview" href="#heading-ensure-forms-are-accessible">Ensure forms are accessible</a><br>– <a class="post-section-overview" href="#heading-caption-and-transcribe-audio-and-video">Caption and transcribe audio and video</a><br>– <a class="post-section-overview" href="#heading-design-consistent-predictable-navigation">Design consistent, predictable navigation</a></li>
<li><a class="post-section-overview" href="#heading-automation-tools-for-accessibility-testing">Automation Tools for Accessibility Testing</a></li>
<li><a class="post-section-overview" href="#heading-embrace-accessibility-as-a-cornerstone-of-web-development">Wrapping Up</a></li>
</ol>
<h2 id="heading-what-is-web-accessibility">What is Web Accessibility?</h2>
<p>Accessibility in web design means creating web pages that can be used by people with a wide range of abilities and disabilities. This encompasses auditory, cognitive, neurological, physical, speech, and visual impairments.</p>
<h3 id="heading-key-principles-of-accessibility">Key Principles of Accessibility</h3>
<p>The Web Content Accessibility Guidelines (WCAG) provide a framework for making web content more accessible to people with a wide range of abilities and disabilities. These guidelines are based on four key principles, often summarized as POUR, each crucial for creating a universally accessible web. </p>
<p>Here's a deeper look into what these principles mean in practice:</p>
<ol>
<li><strong>Perceivable</strong>: Information and user interface components must be presented in ways that all users can perceive. This means providing text alternatives for non-text content (like images), creating content that can be presented in different ways without losing information (such as using a simpler layout), and making it easier for users to see and hear content.<br><strong>Example</strong>: Providing alt text for images. Alt text allows screen reader users to understand the content and context of the images, making visual content accessible.</li>
<li><strong>Operable</strong>: User interface components and navigation must be operable by everyone. This includes ensuring all functionalities are accessible via keyboard, giving users enough time to read and use content, and not designing content in a way that is known to cause seizures.<br><strong>Example</strong>: Implementing keyboard navigation. All interactive elements like links, buttons, and form fields should be accessible using a keyboard, making them accessible to users who cannot use a mouse.</li>
<li><strong>Understandable</strong>: Information and operation of the user interface must be understandable. This means making text readable and understandable, and ensuring that web pages appear and operate in predictable ways.<br><strong>Example</strong>: Using consistent navigation menus. Keeping navigation menus consistent across a website helps users with cognitive disabilities learn and remember how to navigate.</li>
<li><strong>Robust</strong>: Content must be robust enough to be reliably interpreted by a wide variety of user agents, including assistive technologies. This includes ensuring compatibility with current and future user tools.<br><strong>Example</strong>: Using clean, validated HTML. Well-structured and standard-compliant HTML ensures content can be interpreted by different browsers and assistive technologies.</li>
</ol>
<p>By integrating these principles into web design, developers and designers can create more accessible and inclusive digital environments. Each principle plays a crucial role in ensuring that the web is a space for everyone, regardless of their abilities or disabilities.</p>
<h2 id="heading-best-practices-for-web-accessibility">Best Practices for Web Accessibility</h2>
<h3 id="heading-use-semantic-html">Use Semantic HTML</h3>
<p>Semantic HTML involves using HTML elements according to their intended purpose rather than just for presentation. It's about structuring your website with elements that describe their meaning and role in the document structure. </p>
<p>This practice is crucial for assistive technologies, like screen readers, which rely on this structure to interpret and navigate content. </p>
<h3 id="heading-how-to-implement-semantic-html">How to implement semantic HTML</h3>
<p>Consider a typical webpage layout comprising a header, main content, a navigation menu, and a footer. Instead of using non-semantic <code>&lt;div&gt;</code> tags for these sections, you should use the semantic elements <code>&lt;header&gt;</code>, <code>&lt;main&gt;</code>, <code>&lt;nav&gt;</code>, and <code>&lt;footer&gt;</code> respectively.</p>
<p>Here's an example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- Site logo, header content --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">nav</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- Navigation links --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- Main content --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">footer</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- Footer content --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">footer</span>&gt;</span>
</code></pre>
<h3 id="heading-why-semantic-html-is-useful">Why semantic HTML is useful:</h3>
<ol>
<li><strong>Accessibility</strong>: Screen readers can easily navigate and interpret the content. For example, a user can skip directly to the main content or easily find the navigation menu.</li>
<li><strong>SEO benefits</strong>: Search engines favor well-structured content. Semantic elements make it easier for search engine bots to understand the content of a webpage, potentially improving search rankings.</li>
<li><strong>Maintainability</strong>: Semantic HTML leads to cleaner, more readable code, making it easier for developers to understand and maintain.</li>
</ol>
<p>Using semantic HTML is the foundation of web accessibility, ensuring content is accessible and meaningful to all users, including those using assistive technologies.</p>
<h3 id="heading-use-sufficient-contrast">Use Sufficient Contrast</h3>
<p>Contrast refers to the difference in color and brightness between the text and its background. Ensuring sufficient contrast is vital for readability, especially for users with visual impairments like color blindness or low vision. High contrast between text and background makes it easier for these users to read and understand content.</p>
<h3 id="heading-how-to-implement-good-contrast">How to implement good contrast</h3>
<p>Imagine a webpage with light gray text on a white background. This combination might look aesthetically pleasing but can be hard to read for many users. </p>
<p>To improve contrast, you could change the text color to a much darker shade, like black or dark gray.</p>
<pre><code class="lang-css"><span class="hljs-comment">/* Low contrast example */</span>
<span class="hljs-selector-class">.low-contrast-text</span> {
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#757575</span>; <span class="hljs-comment">/* Light gray */</span>
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fff</span>; <span class="hljs-comment">/* White */</span>
}

<span class="hljs-comment">/* Improved contrast */</span>
<span class="hljs-selector-class">.high-contrast-text</span> {
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#000</span>; <span class="hljs-comment">/* Black */</span>
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fff</span>; <span class="hljs-comment">/* White */</span>
}
</code></pre>
<h3 id="heading-why-contrast-is-useful">Why contrast is useful:</h3>
<ol>
<li><strong>Enhanced readability</strong>: High contrast makes the text legible to users with visual impairments and those reading under challenging lighting conditions.</li>
<li><strong>Inclusivity</strong>: It caters to a wider audience, including users with deteriorating vision and those with temporary or situational impairments.</li>
<li><strong>Legal compliance</strong>: Many regions have regulations requiring accessible web content, and sufficient contrast is a common requirement.</li>
</ol>
<p>Tools like the <a target="_blank" href="https://webaim.org/resources/contrastchecker/">WebAIM Contrast Checker</a> can help you evaluate your color choices, ensuring they meet accessibility standards like WCAG. By ensuring sufficient contrast, you not only make your website more accessible but also improve the overall user experience.</p>
<h3 id="heading-make-all-functionality-keyboard-accessible">Make All Functionality Keyboard Accessible</h3>
<p>Ensuring that all functionalities on a website are accessible via keyboard is essential for users who cannot use a mouse due to physical disabilities, temporary injuries, or personal preference. This includes navigating menus, activating buttons and links, filling out forms, and using interactive widgets.</p>
<h3 id="heading-how-to-make-content-keyboard-accessible">How to make content keyboard accessible</h3>
<p>Consider a dropdown menu on a website. Typically, users hover over the menu with a mouse to view the options. </p>
<p>To make this keyboard-accessible, you need to ensure that users can navigate to the menu using the Tab key and expand the menu using the Enter or Space key.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"0"</span>&gt;</span>Menu Item 1
    <span class="hljs-tag">&lt;<span class="hljs-name">ul</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"dropdown-content"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"0"</span>&gt;</span>Sub Item 1<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"0"</span>&gt;</span>Sub Item 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">li</span> <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"0"</span>&gt;</span>Menu Item 2<span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
</code></pre>
<pre><code class="lang-js"><span class="hljs-built_in">document</span>.querySelectorAll(<span class="hljs-string">'li[tabindex="0"]'</span>).forEach(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> {
  item.addEventListener(<span class="hljs-string">'keypress'</span>, <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">e</span>) </span>{
    <span class="hljs-keyword">if</span> (e.key === <span class="hljs-string">'Enter'</span> || e.key === <span class="hljs-string">' '</span>) {
      <span class="hljs-comment">// Code to toggle dropdown</span>
    }
  });
});
</code></pre>
<h3 id="heading-why-keyboard-navigation-is-useful">Why keyboard navigation is useful:</h3>
<ol>
<li><strong>Accessibility for all</strong>: Keyboard accessibility ensures that users with motor disabilities or those who prefer keyboard navigation can use the website effectively.</li>
<li><strong>Enhanced usability</strong>: Keyboard shortcuts can speed up navigation, offering an enhanced experience even for users who can use a mouse.</li>
<li><strong>Compliance with accessibility standards</strong>: Adhering to standards like WCAG and ADA (Americans with Disabilities Act) often requires keyboard accessibility.</li>
</ol>
<p>In practice, keyboard accessibility may involve more than just basic navigation. It also includes managing focus, creating keyboard shortcuts for complex actions, and ensuring custom widgets are keyboard-friendly. By prioritizing keyboard accessibility, you make your website more inclusive and user-friendly.</p>
<h3 id="heading-provide-alt-text-for-images">Provide Alt Text for Images</h3>
<p>Alt text (alternative text) is a concise description of an image's content and function. It's crucial for visually impaired users who rely on screen readers to understand image content. Alt text ensures that even if users can't see the images on a web page, their purpose and message can still be conveyed.</p>
<h3 id="heading-how-to-add-alt-text-to-images">How to add alt text to images</h3>
<p>Suppose your website has an image of a company logo. The alt text should describe the logo, not just state "logo". For instance, <code>alt="FreeCodeCamp's campfire Logo"</code>.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">img</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"freecodecamp-logo.png"</span> <span class="hljs-attr">alt</span>=<span class="hljs-string">"FreeCodeCamp's campfire Logo"</span>&gt;</span>
</code></pre>
<p>For purely decorative images that don't add informational content, use an empty alt attribute (<code>alt=""</code>) to indicate that they can be skipped by screen readers.</p>
<h3 id="heading-why-alt-text-is-useful">Why alt text is useful:</h3>
<ol>
<li><strong>Accessibility Compliance</strong>: Providing alt text is a fundamental aspect of web accessibility, required under WCAG guidelines.</li>
<li><strong>SEO Benefits</strong>: Alt text improves SEO by providing better image context/descriptions, helping search engines index an image properly.</li>
<li><strong>Fallback Content</strong>: If an image fails to load, the alt text will be displayed, helping all users understand what was supposed to be there.</li>
</ol>
<p>Properly implemented alt text makes your website more accessible and inclusive, ensuring that all users, regardless of their ability to see, have access to the information conveyed by images. It's a simple yet impactful practice that enhances the overall user experience.</p>
<h3 id="heading-use-aria-accessible-rich-internet-applications-roles-when-necessary">Use ARIA (Accessible Rich Internet Applications) Roles When Necessary</h3>
<p>ARIA roles and attributes enhance the accessibility of web content, particularly for dynamic content and advanced user interface controls developed with Ajax, HTML, JavaScript, and related technologies. ARIA helps make web content and web applications more accessible to people with disabilities, especially when HTML can't accomplish it alone.</p>
<h3 id="heading-how-to-implement-aria-roles-and-attributes">How to implement ARIA roles and attributes</h3>
<p>Consider a web application with a dynamic content update section, such as a live news feed. Standard HTML alone may not be able to convey the dynamic nature of this content to screen readers. </p>
<p>By using ARIA roles, you can make it clear to assistive technologies that this section of the page is a live region and its updates are important. For instance:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">aria-live</span>=<span class="hljs-string">"polite"</span> <span class="hljs-attr">aria-atomic</span>=<span class="hljs-string">"true"</span>&gt;</span>
  <span class="hljs-comment">&lt;!-- Dynamic content here, like live news updates --&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<p>In this example, <code>aria-live="polite"</code> indicates that updates to this region should be announced by screen readers, but not interrupt the current task, while <code>aria-atomic="true"</code> ensures that the entire region is read as a whole, not just the updated part.</p>
<h3 id="heading-why-aria-is-useful">Why ARIA is useful:</h3>
<ol>
<li><strong>Enhanced screen reader experience</strong>: ARIA roles provide screen reader users with a more comprehensive understanding of what's happening on the page, particularly for dynamic and complex content.</li>
<li><strong>Greater interactivity</strong>: ARIA can make web applications more interactive and usable for people with disabilities, facilitating operations that standard HTML can't handle.</li>
<li><strong>Custom widget accessibility</strong>: For custom widgets that lack semantic HTML equivalents, ARIA roles can define the widget's function, making it accessible.</li>
</ol>
<p>While ARIA is powerful, it's important to use it only when necessary. Native HTML elements should be the first choice as they inherently carry semantic meaning and accessibility features. ARIA should be used as a supplement to enhance accessibility when HTML's semantics don't suffice.</p>
<h3 id="heading-ensure-forms-are-accessible">Ensure Forms are Accessible</h3>
<p>Accessible forms are vital for users with disabilities to interact with a site, input data, and utilize services. Ensuring that form elements are accessible means they can be easily navigated, understood, and filled out by everyone, including those using screen readers or keyboard navigation.</p>
<h3 id="heading-how-to-make-forms-accessible">How to make forms accessible</h3>
<p>Imagine a simple contact form with fields for name, email, and a message. For each form element, use a <code>&lt;label&gt;</code> tag to provide a clear description. Ensure that each <code>&lt;label&gt;</code> is associated with its respective form control using the <code>for</code> attribute, which matches the <code>id</code> of the input element. This is crucial for screen reader users to understand what each field represents.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">form</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"name"</span>&gt;</span>Name:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"text"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"name"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"name"</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"email"</span>&gt;</span>Email:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"email"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"email"</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"message"</span>&gt;</span>Message:<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">textarea</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"message"</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"message"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">textarea</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"submit"</span>&gt;</span>Submit<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">form</span>&gt;</span>
</code></pre>
<h3 id="heading-why-accessible-forms-are-useful">Why accessible forms are useful:</h3>
<ol>
<li><strong>Clarity and context</strong>: Labels provide context to users, especially those using screen readers, about what type of information is expected in each field.</li>
<li><strong>Error handling</strong>: Accessible forms should also handle errors clearly, informing users about what went wrong and how to fix it. This can include real-time validation feedback and error messages that are announced by screen readers.</li>
<li><strong>Keyboard navigation</strong>: All form controls should be navigable using the keyboard, allowing users who can't use a mouse to interact fully with the form.</li>
</ol>
<p>Accessible forms not only comply with accessibility standards but also enhance the overall user experience, making your website more inclusive and user-friendly.</p>
<h3 id="heading-caption-and-transcribe-audio-and-video">Caption and Transcribe Audio and Video</h3>
<p>Providing captions for video content and transcriptions for audio is crucial for accessibility. Captions and transcriptions ensure that deaf or hard-of-hearing users, as well as those who prefer reading to listening, can access audio and video content.</p>
<h3 id="heading-how-to-make-audio-and-video-content-accessible">How to make audio and video content accessible</h3>
<p>For a video on your website, include closed captioning that accurately reflects the spoken content and other auditory cues. You can use HTML5's <code>&lt;track&gt;</code> element to specify caption files. Similarly, for audio content like podcasts or interviews, provide a text transcription.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">video</span> <span class="hljs-attr">controls</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">source</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"video.mp4"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"video/mp4"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">track</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"captions_en.vtt"</span> <span class="hljs-attr">kind</span>=<span class="hljs-string">"captions"</span> <span class="hljs-attr">srclang</span>=<span class="hljs-string">"en"</span> <span class="hljs-attr">label</span>=<span class="hljs-string">"English"</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">video</span>&gt;</span>
</code></pre>
<p>In this example, a WebVTT (.vtt) file is used for captions. Ensure the captions are synchronized with the audio and include descriptions of relevant non-speech audio.</p>
<h3 id="heading-why-captions-and-transcriptions-are-useful">Why captions and transcriptions are useful</h3>
<ol>
<li><strong>Accessibility for hearing impaired</strong>: Captions and transcriptions are essential for users who are deaf or hard of hearing, enabling them to access content that would otherwise be inaccessible.</li>
<li><strong>Enhanced comprehension</strong>: They also benefit users who are not fluent in the language of the video or have difficulty understanding the speech.</li>
<li><strong>Flexible viewing</strong>: Captions allow content to be consumed in sound-sensitive environments, like workplaces or libraries.</li>
</ol>
<p>Remember to regularly check the accuracy and readability of your captions and transcriptions. Well-implemented captions and transcriptions not only make your audio and video content accessible but also enhance the overall engagement and reach of your content.</p>
<h3 id="heading-design-consistent-predictable-navigation">Design Consistent, Predictable Navigation</h3>
<p>Designing a website with consistent and predictable navigation is key to accessibility. It allows users, especially those with cognitive disabilities, to learn the navigation pattern quickly, enhancing their ability to find information and navigate your site effectively.</p>
<h3 id="heading-how-to-design-effective-navigation">How to design effective navigation</h3>
<p>Consider a website with a top navigation menu. The menu items should be in a logical order and remain consistent across all pages. Avoid changing the order of menu items or their location on different pages.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">nav</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">ul</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/"</span>&gt;</span>Home<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/about"</span>&gt;</span>About Us<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/services"</span>&gt;</span>Services<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">li</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"/contact"</span>&gt;</span>Contact<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">li</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ul</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>
</code></pre>
<p>In this example, the navigation structure is simple and straightforward. It's important to maintain this structure and order consistently throughout the website.</p>
<h3 id="heading-why-good-navigation-is-useful">Why good navigation is useful:</h3>
<ol>
<li><strong>Ease of use</strong>: A consistent navigation structure helps users understand and remember how to interact with your website, reducing confusion and frustration.</li>
<li><strong>Improved orientation</strong>: Users can better orient themselves and understand their current location within the website.</li>
<li><strong>Support for assistive technologies</strong>: Consistent navigation is easier for screen readers and other assistive technologies to interpret, providing a smoother browsing experience for users relying on these tools.</li>
</ol>
<p>By ensuring that your website's navigation is consistent and predictable, you enhance the usability for all users, making your website more accessible and user-friendly.</p>
<h2 id="heading-automation-tools-for-accessibility-testing">Automation Tools for Accessibility Testing</h2>
<p>Incorporating automation tools into the accessibility testing process can significantly enhance efficiency and coverage. These tools can swiftly identify areas of non-compliance, allowing for prompt rectifications. </p>
<p>Below are some key tools with link to their websites if you want to explore more:</p>
<h3 id="heading-1-axe-accessibility-checkerhttpswwwdequecomaxe">1. <a target="_blank" href="https://www.deque.com/axe/">Axe Accessibility Checker</a></h3>
<p>Axe is a versatile browser extension and testing tool available for Chrome, Firefox, and Edge. It provides reliable and detailed issue reporting, making it ideal for quick checks and in-depth analysis.</p>
<h3 id="heading-2-wave-web-accessibility-evaluation-toolhttpswavewebaimorg">2. <a target="_blank" href="https://wave.webaim.org/">WAVE (Web Accessibility Evaluation Tool)</a></h3>
<p>WAVE, offered as a browser extension, visually represents potential accessibility problems on web pages, helping to pinpoint issues with color contrast, alt text, and ARIA roles.</p>
<h3 id="heading-3-google-lighthousehttpsdevelopersgooglecomwebtoolslighthouse">3. <a target="_blank" href="https://developers.google.com/web/tools/lighthouse">Google Lighthouse</a></h3>
<p>Integrated into Google Chrome's Developer Tools, Lighthouse features an accessibility audit tool that highlights issues and provides actionable recommendations.</p>
<h3 id="heading-4-tenoniohttpswwwtenonio">4. <a target="_blank" href="https://www.tenon.io/">Tenon.io</a></h3>
<p>Tenon.io is a comprehensive web-based tool for detailed accessibility testing. It can be integrated into development workflows for automated testing during the build process.</p>
<h3 id="heading-5-jaws-inspecthttpswwwtpgicomjaws-inspect">5. <a target="_blank" href="https://www.tpgi.com/jaws-inspect/">JAWS Inspect</a></h3>
<p>JAWS Inspect translates screen reader outputs into a visual format, aiding in the testing of screen reader compatibility and navigability.</p>
<h3 id="heading-6-color-contrast-analyzerhttpswwwpaciellogroupcomresourcescontrastanalyser">6. <a target="_blank" href="https://www.paciellogroup.com/resources/contrastanalyser/">Color Contrast Analyzer</a></h3>
<p>This tool assists in evaluating the contrast between text and its background, ensuring readability for users with visual impairments.</p>
<h3 id="heading-7-accessibility-insightshttpsaccessibilityinsightsio">7. <a target="_blank" href="https://accessibilityinsights.io/">Accessibility Insights</a></h3>
<p>Developed by Microsoft, Accessibility Insights offers a suite of tools, including a web tool for Chrome and Edge, to guide manual testing alongside automated checks.</p>
<h3 id="heading-8-pa11yhttpspa11yorg">8. <a target="_blank" href="https://pa11y.org/">Pa11y</a></h3>
<p>Pa11y is a command-line tool that runs automated accessibility tests on web pages, customizable for integration into development processes.</p>
<p>By leveraging these tools, developers and designers can ensure their websites meet accessibility standards, providing an inclusive experience for all users. Regular use, combined with manual testing and user feedback, creates a comprehensive approach to maintaining and enhancing web accessibility.</p>
<h2 id="heading-embrace-accessibility-as-a-cornerstone-of-web-development">Embrace Accessibility as a Cornerstone of Web Development</h2>
<p>In conclusion, the integration of web accessibility best practices is not just a matter of compliance but a commitment to inclusivity and universal design. The digital world is for everyone, and ensuring that web content is accessible to all, including those with disabilities, is a fundamental responsibility of web developers and designers.</p>
<p>Utilizing tools like Axe, WAVE, Google Lighthouse, and others, combined with manual testing and adherence to guidelines like WCAG, can significantly improve the accessibility of web content. By doing so, we open up our digital spaces to a wider audience, enhance user experience, and foster an environment of inclusivity.</p>
<p>Accessible web design benefits everyone, not just those with disabilities. It leads to cleaner code, better SEO, and a more flexible and resilient website. As the web continues to evolve, prioritizing accessibility will be crucial in creating a more connected and inclusive world. Remember, when we design for accessibility, we improve the web for everyone.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Comment Your JavaScript Code ]]>
                </title>
                <description>
                    <![CDATA[ Writing comments in JavaScript is crucial for code readability, maintainability, and developer collaboration. Comments serve as notes within the codebase, explaining its functionality and logic, or providing context.  In this article, I will explain ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/comment-your-javascript-code/</link>
                <guid isPermaLink="false">66b902ae472b70138041a570</guid>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ code comments ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Md. Fahim Bin Amin ]]>
                </dc:creator>
                <pubDate>Mon, 11 Dec 2023 21:55:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2023/12/Comment-Your-JS-Code-fCC.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Writing comments in JavaScript is crucial for code readability, maintainability, and developer collaboration. Comments serve as notes within the codebase, explaining its functionality and logic, or providing context. </p>
<p>In this article, I will explain the significance of commenting your code, best practices to follow, and examples showcasing effective commenting in JavaScript.</p>
<h2 id="heading-why-comments-are-important-in-javascript">Why Comments are Important in JavaScript</h2>
<h3 id="heading-they-enhance-code-readability">They enhance code readability:</h3>
<p>Comments provide clarity to code, making it easier for developers to understand the code's purpose and functionality. Comments act as a guide, especially when you need to revisit older code after a period of time.</p>
<p>Consider this un-commented code:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateTotal</span>(<span class="hljs-params">price, quantity</span>) </span>{
    <span class="hljs-keyword">return</span> price * quantity;
}

<span class="hljs-keyword">let</span> totalPrice = calculateTotal(<span class="hljs-number">25</span>, <span class="hljs-number">5</span>);
<span class="hljs-built_in">console</span>.log(totalPrice); <span class="hljs-comment">// Output: 125</span>
</code></pre>
<p>It is quite difficult for us to understand what the code does, right? Now, let's add comments for clarity:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Calculates the total cost by multiplying the price per item with the quantity</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateTotal</span>(<span class="hljs-params">price, quantity</span>) </span>{
    <span class="hljs-keyword">return</span> price * quantity;
}

<span class="hljs-comment">// Example usage: Calculates the total price for 5 items at $25 each by multiplying the price per item ($25) with the quantity (5), and stores the result in the totalPrice variable.</span>
<span class="hljs-keyword">let</span> totalPrice = calculateTotal(<span class="hljs-number">25</span>, <span class="hljs-number">5</span>);
<span class="hljs-built_in">console</span>.log(totalPrice); <span class="hljs-comment">// Output: 125</span>
</code></pre>
<p>With comments, it is quite understandable what each part of the code does, and it also enhances its readability.</p>
<h3 id="heading-they-facilitate-collaboration">They facilitate collaboration:</h3>
<p>In a team environment, comments aid collaboration by allowing developers to comprehend each other's code, making it easier to work together on projects.</p>
<p>Imagine working in a team where different developers handle various parts of a project. Clear comments aid in understanding each other's code. Here's an example:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Validates the format of the provided email address using a regular expression, which checks for the presence of "@" symbol, domain name, and top-level domain (TLD) in the email</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">validateEmail</span>(<span class="hljs-params">email</span>) </span>{
    <span class="hljs-comment">// Regular expression pattern to match the standard email format</span>
    <span class="hljs-keyword">const</span> emailRegex = <span class="hljs-regexp">/^[^\s@]+@[^\s@]+\.[^\s@]+$/</span>;
    <span class="hljs-keyword">return</span> emailRegex.test(email);
}
</code></pre>
<p>In a collaborative setting, another developer can quickly comprehend the purpose of the <code>validateEmail</code> function due to the comment, enabling smoother teamwork. This would've been very difficult without the comments indicating what the code block does.</p>
<h3 id="heading-they-make-maintenance-and-debugging-easier">They make maintenance and debugging easier:</h3>
<p>Well-commented code simplifies maintenance and debugging. Comments can highlight potential issues, outline the reasoning behind specific solutions, and aid in locating bugs.</p>
<p>Comments assist in debugging and maintaining code. Consider the following commented code:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Finds the maximum number between num1 and num2 using a ternary operator for comparison and returns the larger number</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">findMax</span>(<span class="hljs-params">num1, num2</span>) </span>{
    <span class="hljs-comment">/* Using ternary operator to compare num1 and num2
       and return the larger number */</span>
    <span class="hljs-keyword">return</span> (num1 &gt; num2) ? num1 : num2;
}
</code></pre>
<p>If a bug arises or modifications are needed, the comment clarifies the logic used, aiding in swift debugging or updates.</p>
<h2 id="heading-best-practices-for-commenting-in-javascript">Best Practices for Commenting in JavaScript</h2>
<h3 id="heading-use-descriptive-comments">Use descriptive comments:</h3>
<p>Explain the purpose of functions, variables, or complex logic using descriptive comments. This helps other developers, including your future self, understand the code's intention.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Calculates the area of a circle using the provided radius by multiplying the square of the radius by the mathematical constant π (pi)</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateCircleArea</span>(<span class="hljs-params">radius</span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.PI * radius * radius;
}
</code></pre>
<p>Descriptive comments like this explain the purpose of functions or operations, aiding in understanding the code's intention.</p>
<h3 id="heading-avoid-over-commenting">Avoid over-commenting:</h3>
<p>While comments are beneficial, excessive commenting can clutter the code. Aim for a balance where comments add value without stating the obvious.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Variable to store user data</span>
<span class="hljs-keyword">let</span> userData = fetchUserData(); <span class="hljs-comment">// Fetch user data from the server</span>
</code></pre>
<p>In this case, the comment merely reiterates what the code already expresses clearly. Avoiding over-commenting maintains code clarity.</p>
<h3 id="heading-update-comments-regularly">Update comments regularly:</h3>
<p>As code evolves, ensure comments remain accurate and aligned with the code changes. Outdated comments can lead to confusion.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Function to calculate the area of a rectangle</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateRectangleArea</span>(<span class="hljs-params">length, width</span>) </span>{
    <span class="hljs-keyword">return</span> length * width;
    <span class="hljs-comment">// Updated comment: Area calculated by multiplying length and width</span>
}
</code></pre>
<p>Ensuring that comments align with the current functionality or logic of the code is vital for accurate documentation.</p>
<h3 id="heading-comment-complex-sections">Comment complex sections:</h3>
<p>When dealing with intricate algorithms or unconventional solutions, detailed comments explaining the logic can be immensely helpful.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Performs a complex calculation on the provided data, involving multiple steps including data preprocessing, calculation based on preprocessed data, and returning the final result</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">performComplexCalculation</span>(<span class="hljs-params">data</span>) </span>{
    <span class="hljs-comment">/* 
        Complex logic involving multiple steps:
        - Step 1: Data preprocessing
        - Step 2: Calculation based on preprocessed data
        - Step 3: Final result
    */</span>
    <span class="hljs-comment">// ... complex calculation logic</span>
}
</code></pre>
<p>For intricate algorithms or multi-step processes, detailed comments explaining each step can immensely aid in understanding.</p>
<h2 id="heading-types-of-comments-in-javascript">Types of Comments in JavaScript</h2>
<h3 id="heading-single-line-comments">Single-line comments:</h3>
<p>In JavaScript, single-line comments start with <code>//</code>. They're suitable for brief explanations or annotating specific lines. Keep in mind that the two forward slashes don't have any spaces between them.</p>
<p>Example:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// This function calculates the square of a number</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">square</span>(<span class="hljs-params">number</span>) </span>{
    <span class="hljs-keyword">return</span> number * number;
}
</code></pre>
<h3 id="heading-multi-line-comments">Multi-line comments:</h3>
<p>Multi-line comments begin with <code>/*</code> and end with <em><code>/</code>.</em> They are useful for commenting out blocks of code or providing longer explanations. Keep in mind that the forward slash and the asterisk (<code>*</code>) don't have any spaces between them.</p>
<p>Example:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">/*
    This block of code finds the maximum of two numbers
    and returns the larger number.
*/</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">findMax</span>(<span class="hljs-params">num1, num2</span>) </span>{
    <span class="hljs-comment">// Logic to find the maximum</span>
    <span class="hljs-keyword">return</span> (num1 &gt; num2) ? num1 : num2;
}
</code></pre>
<h3 id="heading-jsdoc-comments">JSDoc comments:</h3>
<p>JSDoc is a convention for adding comments to JavaScript code that enables the automatic generation of documentation. It uses a specific syntax to describe functions, parameters, return values, and so on.</p>
<p>Example:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">/**
 * Calculates the area of a rectangle
 * <span class="hljs-doctag">@param <span class="hljs-type">{number}</span> <span class="hljs-variable">length</span></span> - The length of the rectangle
 * <span class="hljs-doctag">@param <span class="hljs-type">{number}</span> <span class="hljs-variable">width</span></span> - The width of the rectangle
 * <span class="hljs-doctag">@returns <span class="hljs-type">{number}</span> </span>- The area of the rectangle
 */</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">calculateArea</span>(<span class="hljs-params">length, width</span>) </span>{
    <span class="hljs-keyword">return</span> length * width;
}
</code></pre>
<h2 id="heading-practice-commenting-your-code">Practice Commenting Your Code 📝✍️</h2>
<p>Learning without practicing is an incomplete process. So here's <a target="_blank" href="https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-javascript/comment-your-javascript-code"><strong>a learning challenge from the freeCodeCamp Certification Course</strong></a> where you will learn how comments work in JavaScript, and how you can use them in your code. </p>
<p>In this challenge, you will try to understand how single-line comments and multiline comments work.</p>
<p>I've included the solution next in case you can't solve the challenge yourself.</p>
<p>If you'd like to watch a video on this topic as well, you can find it here:</p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/oqFs3bRQDSY" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-the-solution-to-the-challenge">The Solution to the Challenge</h2>
<p>Make sure that you have tried to solve this challenge on your own before checking my solution.</p>
<p>Alright, if you're ready...here it is:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Fahim</span>

<span class="hljs-comment">/*
My
Name
Is
Fahim
*/</span>
</code></pre>
<p>The first one is the single-line comment, and the second one is the multi-line comment.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Commenting on JavaScript code is an essential practice in software development. It improves code comprehension, aids collaboration, and facilitates maintenance and debugging. </p>
<p>By following best practices and using various comment types, we can create codebases that are easier to understand, maintain, and build upon.</p>
<p>I hope you have gained some valuable insights from the article. </p>
<p>If you have enjoyed the procedures step-by-step, then don't forget to let me know on <a target="_blank" href="https://twitter.com/Fahim_FBA">Twitter/X</a> or <a target="_blank" href="https://www.linkedin.com/in/fahimfba/">LinkedIn</a>.</p>
<p>You can follow me on <a target="_blank" href="https://github.com/FahimFBA">GitHub</a> as well if you are interested in open source. Make sure to check <a target="_blank" href="https://fahimbinamin.com/">my website</a> (<a target="_blank" href="https://fahimbinamin.com/">https://fahimbinamin.com/</a>) as well!</p>
<p>If you like to watch programming and technology-related videos, then you can check my <a target="_blank" href="https://www.youtube.com/@FahimAmin?sub_confirmation=1">YouTube channel</a>, too. You can also check my other writings on <a target="_blank" href="https://dev.to/fahimfba">Dev.to</a>.</p>
<p>All the best for your programming and development journey. 😊</p>
<p>You can do it! Don't give up, never! ❤️</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
