<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" 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">
    <channel>
        <title>Mustaque Nadim</title>
        <link>https://mustaquenadim.com</link>
        <description>Mustaque Nadim is a passionate full-stack developer from Bangladesh. Expert in React, Next.js, Node.js, and modern web technologies. Building fast, scalable applications with practical insights on AI, performance, and developer productivity.</description>
        <lastBuildDate>Tue, 05 May 2026 12:47:57 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Mustaque Nadim</title>
            <url>https://mustaquenadim.com/og.png</url>
            <link>https://mustaquenadim.com</link>
        </image>
        <copyright>All rights reserved 2026, Mustaque Nadim</copyright>
        <atom:link href="https://mustaquenadim.com/rss.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[The Myth of the 'Perfect' Launch]]></title>
            <link>https://mustaquenadim.com/blog/the-myth-of-the-perfect-launch</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/the-myth-of-the-perfect-launch</guid>
            <pubDate>Tue, 05 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why waiting for everything to be perfect before shipping is the fastest way to guarantee failure.]]></description>
            <content:encoded><![CDATA[<p>You've been working on your product for six months. It's almost perfect. Just a few more tweaks. Polish the landing page. Refactor the auth module. Add that one more feature everyone keeps asking about.</p>
<p>Two years later, it still hasn't shipped.</p>
<p>I've seen this pattern a thousand times. Smart, ambitious people building beautiful things in a cave, waiting for the moment when it's "ready." That moment never comes because perfection is a moving target.</p>
<h2>The Cost of Waiting</h2>
<p>Every week you don't ship is a week your competition is gaining users. It's a week you're not getting feedback. It's a week you're not learning what actually matters to your customers versus what matters to you.</p>
<p>There's also a psychological cost. Shipping is terrifying, so we convince ourselves that "not ready" is the real reason. But deep down, we know it's fear dressed up as perfectionism.</p>
<h2>What "Good Enough" Actually Means</h2>
<p>Shipping doesn't mean shipping garbage. It means shipping something that:</p>
<ul>
<li>Solves a real problem for real users</li>
<li>Doesn't actively harm those users</li>
<li>Can be improved based on actual feedback</li>
</ul>
<p>It does <em>not</em> mean:</p>
<ul>
<li>Perfect performance</li>
<li>Zero bugs</li>
<li>Every feature you dreamed of</li>
<li>A beautiful UI (though nice UI helps)</li>
<li>Everyone you know loves it</li>
</ul>
<h2>The Magic of Iteration</h2>
<p>The best products weren't built in isolation. They were built in the open, with real users, making changes based on what people actually wanted (not what the builder thought they wanted).</p>
<p>GitHub had a janky interface. Slack had bugs. Twitter was a text-only status feed. None of them waited for perfection before they shipped.</p>
<p>They shipped, listened, and iterated.</p>
<h2>Ship Today</h2>
<p>Stop perfecting. Stop planning. Stop waiting for the stars to align.</p>
<p>Pick a launch date that's 30 days away. Cut your scope to fit that date. Ship something imperfect but real on that date. Then start collecting feedback and iterating.</p>
<p>Your "perfect" product shipping never is infinitely worse than your "good enough" product shipping today.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[The Silent Cost of Context Switching]]></title>
            <link>https://mustaquenadim.com/blog/silent-cost-of-context-switching</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/silent-cost-of-context-switching</guid>
            <pubDate>Fri, 01 May 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why 'just a quick question' is never just a quick question, and how to protect your focus.]]></description>
            <content:encoded><![CDATA[<p>"Hey, do you have two minutes for a quick question?"</p>
<p>It's the most expensive sentence in software engineering.</p>
<p>We tend to measure the cost of an interruption by the duration of the interruption itself. If answering a Slack message takes two minutes, we assume we lost two minutes of productivity.</p>
<p>This is a dangerous illusion.</p>
<p>The real cost isn't the two minutes. It's the 20 minutes it takes to rebuild the delicate, invisible scaffolding of context in your brain.</p>
<h2>The Mental House of Cards</h2>
<p>Programming is an exercise in holding a massive amount of abstract state in your head simultaneously.</p>
<p>When you're deep in the zone, you are tracking the flow of data across five different files, remembering that edge case you need to handle on line 42, and holding onto the architecture of a database schema. It's a mental house of cards.</p>
<p>When someone asks you a "quick question," that house of cards instantly collapses.</p>
<p>You answer the question. You go back to your editor. And you stare blankly at the screen. <em>What was I doing? Wait, why did I pass this variable here?</em> You have to start rebuilding the house from the ground up.</p>
<h2>The Myth of Multitasking</h2>
<p>Humans cannot multitask. We can only task-switch rapidly. And every switch incurs a cognitive tax.</p>
<p>If you are trying to write a complex feature while keeping an eye on your email, a Slack channel, and a CI/CD pipeline, you are operating at a fraction of your actual cognitive capacity. You are spending more energy switching contexts than you are doing actual work.</p>
<p>This is why a developer can sit at their desk for 8 hours, answer 50 messages, attend 3 meetings, and end the day feeling utterly exhausted while having written zero lines of code.</p>
<h2>Protecting the Zone</h2>
<p>If you want to do meaningful work, you have to ruthlessly protect your context.</p>
<ol>
<li><strong>Batch your communication:</strong> Don't keep Slack open on a second monitor. Check it once an hour, or once every two hours. Close your email.</li>
<li><strong>Communicate your boundaries:</strong> Tell your team, "I'm going heads-down for the next two hours. If production is literally on fire, call my phone. Otherwise, I'll reply at 2 PM."</li>
<li><strong>Use physical cues:</strong> Put on noise-canceling headphones. Turn on "Do Not Disturb" on your OS.</li>
</ol>
<p>As an industry, we need to stop treating synchronous communication as the default. Asynchronous communication should be the rule; synchronous communication should be reserved for actual emergencies.</p>
<p>Your focus is your most valuable asset. Stop giving it away for "just a quick question."</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[How Adult Content Destroys Your Brain: The Science Behind the Damage]]></title>
            <link>https://mustaquenadim.com/blog/how-adult-content-impairs-brain-function</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/how-adult-content-impairs-brain-function</guid>
            <pubDate>Thu, 23 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[A detailed, evidence-based breakdown of how pornography consumption alters brain chemistry, impairs cognitive function, and affects focus, motivation, and relationships.]]></description>
            <content:encoded><![CDATA[<p>We live in an age where adult content is just a few clicks away. It's everywhere, normalized, and easily accessible. But while we carefully monitor what we eat and how we exercise, we rarely stop to think about what our consumption does to our brain.</p>
<p>The truth is uncomfortable: frequent pornography consumption doesn't just waste your time. It physically alters your brain in ways that can profoundly impact your focus, motivation, relationships, and overall mental performance.</p>
<p>Let me walk you through the science—explained simply, so you can understand exactly what's happening inside your skull.</p>
<hr>
<h2>The Science Made Simple: How Your Brain Works</h2>
<p>Before we dive in, let's understand the basics.</p>
<p>Your brain has something called a <strong>reward system</strong>. Think of it as an internal scoring mechanism. When you do something good for your survival—eat food, exercise, connect with people—your brain releases a chemical called <strong>dopamine</strong>. Dopamine makes you feel good and tells your brain: "Do this again."</p>
<p>This is how we survive. It's how humans are motivated to eat, socialize, reproduce, and pursue goals.</p>
<p>Here's the key concept: <strong>dopamine is about anticipation, not satisfaction.</strong></p>
<p>The higher the dopamine spike, the more your brain pays attention and remembers the behavior. Your brain learns: "This action leads to a reward. Remember this."</p>
<p>Now, here's where adult content becomes problematic.</p>
<hr>
<h2>What Happens When You Watch Porn</h2>
<p>When you consume pornography, your brain releases a massive amount of dopamine—far more than you'd get from real-world activities like exercising, studying, or even physical intimacy with a real person.</p>
<p>Why is this a problem?</p>
<h3>1. The Dopamine Overdose</h3>
<p>Natural rewards—like food, exercise, or social connection—produce a moderate, gradual dopamine release. You feel good, but your brain maintains balance.</p>
<p>Pornography produces a <strong>dopamine spike that's 2 to 10 times higher</strong> than natural rewards. Your brain experiences an intensity it was never designed to handle.</p>
<p>When you flood your system with this much dopamine regularly, two things happen:</p>
<p><strong>Tolerance</strong>: Just like a drug user needs more to get the same high, you need more extreme content to feel the same level of stimulation. What excited you a year ago feels boring now.</p>
<p><strong>Desensitization</strong>: Your brain tries to protect itself from being overwhelmed. It actually reduces the number of dopamine receptors—making your brain less sensitive to normal, healthy pleasures.</p>
<h3>2. Your Brain Rewires Itself</h3>
<p>Your brain is incredibly adaptable—it constantly changes based on what you do. This is called <strong>neuroplasticity</strong>. It sounds like a good thing, but it cuts both ways.</p>
<p>When you repeatedly刺激 your reward system with pornography, your brain adapts:</p>
<ul>
<li><strong>Stronger neural pathways form</strong> for viewing porn</li>
<li><strong>Weaker pathways form</strong> for normal social interaction, delayed gratification, and long-term goals</li>
<li>The brain starts prioritizing the easy, instant reward over challenging but meaningful activities</li>
</ul>
<p>In brain scans, this looks remarkably similar to what happens in the brains of drug addicts. The same circuits light up. The same structural changes occur.</p>
<hr>
<h2>The Impact on Focus and Concentration</h2>
<p>One of the most noticeable effects is on your ability to focus.</p>
<p>If you've ever tried to work or study after consuming adult content, you probably noticed:</p>
<ul>
<li>Your mind feels scattered</li>
<li>Tasks that normally interest you feel boring</li>
<li>You constantly drift back to the same mental loops</li>
<li>Simple work feels exhausting</li>
</ul>
<p>This isn't coincidence. Here's what's happening:</p>
<p>After the dopamine spike comes a crash. Your brain has been flooded with chemicals, and now it needs to recalibrate. This creates:</p>
<ul>
<li>Mental fog</li>
<li>Reduced ability to sustain attention</li>
<li>Restlessness and difficulty relaxing without stimulation</li>
<li>Antsiness when doing anything that doesn't provide instant gratification</li>
</ul>
<p><strong>The irony is painful</strong>: the very thing that gives you a quick dopamine hit makes everything else feel less satisfying. Your brain's baseline for "interesting" keeps getting reset higher.</p>
<p>Over time, this creates a cycle:</p>
<ol>
<li>You consume adult content → massive dopamine spike</li>
<li>You crash → brain fog and restlessness</li>
<li>You can't focus on normal tasks → they feel boring</li>
<li>You seek more stimulation → consume more content</li>
<li>Repeat</li>
</ol>
<p>This is how your attention span gets destroyed.</p>
<hr>
<h2>What Happens to Your Prefrontal Cortex</h2>
<p>Your prefrontal cortex is the part of your brain responsible for:</p>
<ul>
<li>Decision making</li>
<li>Impulse control</li>
<li>Long-term planning</li>
<li>Self-discipline</li>
<li>Emotional regulation</li>
<li>Abstract thinking</li>
</ul>
<p>It's essentially the "adult" part of your brain—the part that helps you make smart choices instead of impulsive ones.</p>
<p>Research has shown that heavy pornography consumers often have:</p>
<ul>
<li><strong>Reduced gray matter</strong> in the prefrontal cortex (that means less brain tissue in the area responsible for self-control)</li>
<li><strong>Weaker connectivity</strong> between the reward system and prefrontal cortex (your "brakes" don't work as well)</li>
<li><strong>Decreased activity</strong> in the prefrontal cortex during cognitive tasks</li>
</ul>
<p>In plain English: your ability to control impulses, plan for the future, and make good decisions literally weakens.</p>
<p>This is why people who consume a lot of porn often report:</p>
<ul>
<li>Procrastination getting worse</li>
<li>Difficulty resisting immediate pleasures</li>
<li>Less motivation to work toward long-term goals</li>
<li>Emotional instability</li>
</ul>
<hr>
<h2>The Impact on Real-World Intimacy</h2>
<p>Here's a topic that gets less attention but affects millions of men:</p>
<p><strong>Pornography-induced erectile dysfunction (PIED)</strong>.</p>
<p>This is exactly what it sounds like—difficulty achieving or maintaining arousal with real sexual partners, but no problem with porn.</p>
<p>The mechanism is straightforward:</p>
<ul>
<li>Your brain rewires to associate sexual arousal specifically with pixels on a screen</li>
<li>Real human touch, smell, and presence don't trigger the same intense dopamine response</li>
<li>The brain's arousal pathways, shaped by endless novelty in porn, can't activate fully with a single real partner</li>
</ul>
<p>This is becoming increasingly common among young men who have grown up with unlimited internet porn. It's not a matter of "not being attracted to your partner"—it's that their brain has been trained on a completely different type of stimulation.</p>
<p>The solution isn't medication. It's retraining the brain—which takes time and abstinence.</p>
<hr>
<h2>Social Anxiety and Connection</h2>
<p>Another significant impact is on your social functioning.</p>
<p>Brain studies show that heavy consumers often have:</p>
<ul>
<li>Reduced activity in brain regions associated with social processing</li>
<li>Difficulty reading facial expressions</li>
<li>Less empathy</li>
<li>Greater preference for isolation</li>
</ul>
<p>When you spend大量 time in a parasocial, one-sided interaction with screens, your social skills atrophy. Real human interaction feels uncomfortable, awkward, or less rewarding than the controlled, on-demand stimulation of porn.</p>
<p>Many former consumers report that after quitting, they gradually felt more comfortable in social situations, made better eye contact, and found real conversations more engaging.</p>
<hr>
<h2>The Addiction Component</h2>
<p>Let's address the word that makes people uncomfortable: <strong>addiction</strong>.</p>
<p>Is pornography addictive? The research says yes—neurologically, it operates on the same principles as substance addiction:</p>
<ul>
<li><strong>Binging</strong>: Consuming more than intended</li>
<li><strong>Withdrawal</strong>: Irritability, anxiety, restlessness when unable to access</li>
<li><strong>Loss of control</strong>: Unable to stop despite wanting to</li>
<li><strong>Continued use despite negative consequences</strong>: Relationship problems, career impacts, health issues</li>
<li><strong>Tolerance</strong>: Needing more for the same effect</li>
<li><strong>Craving</strong>: Strong urges triggered by triggers/stress/boredom</li>
</ul>
<p>Brain scans of porn addicts show the same patterns as drug addicts: hyperactive reward circuitry, desensitized dopamine receptors, and impaired prefrontal control.</p>
<p>This doesn't mean every consumer is addicted. But the potential for addiction is real—and the line between casual use and problematic use is often blurrier than people think.</p>
<hr>
<h2>The Recovery: Can Your Brain Heal?</h2>
<p>Here's the good news: <strong>yes, your brain can heal</strong>.</p>
<p>Neuroplasticity works in both directions. Your brain didn't become this way overnight, and it won't fix itself overnight either—but it absolutely can recover.</p>
<h3>Timeline for Recovery</h3>
<p>Research and anecdotal evidence from communities like NoFap suggest:</p>
<ul>
<li>
<p><strong>Days 1-7</strong>: Initial withdrawal. Irritability, brain fog, urges. Your brain is adjusting to the absence of super-normal stimulation.</p>
</li>
<li>
<p><strong>Days 7-30</strong>: Symptoms often peak then gradually decrease. Sleep improves. Mental clarity starts returning.</p>
</li>
<li>
<p><strong>Days 30-90</strong>: The brain begins to renormalize. Dopamine sensitivity returns—normal activities start feeling more enjoyable again. Many report improved focus and motivation.</p>
</li>
<li>
<p><strong>90+ days</strong>: Continued improvement. Many report significant changes in energy, motivation, social confidence, and ability to concentrate.</p>
</li>
</ul>
<h3>What Helps the Healing Process</h3>
<ol>
<li>
<p><strong>Complete abstinence from triggers</strong>: Use website blockers. Remove easy access. Delete accounts.</p>
</li>
<li>
<p><strong>Replace the habit</strong>: When you feel the urge, do something else—exercise, cold shower, call a friend, go outside.</p>
</li>
<li>
<p><strong>Exercise</strong>: Physical activity helps restore dopamine sensitivity naturally.</p>
</li>
<li>
<p><strong>Meditation</strong>: Builds prefrontal cortex activity and improves impulse control.</p>
</li>
<li>
<p><strong>Social connection</strong>: Force yourself into real human interaction. It rebuilds the atrophied social pathways.</p>
</li>
<li>
<p><strong>Sleep</strong>: Your brain heals during sleep. Prioritize it.</p>
</li>
<li>
<p><strong>Patience</strong>: This is a marathon, not a sprint. 90 days is a reasonable starting point to see meaningful changes.</p>
</li>
</ol>
<hr>
<h2>Why This Matters</h2>
<p>We spend so much time optimizing our external environment—better tools, better routines, better habits. But we rarely think about optimizing our internal environment.</p>
<p>Your brain is the tool you use to do everything else. To think, create, connect, and build a life.</p>
<p>If you're consuming high-dopamine content regularly and noticing:</p>
<ul>
<li>Poor focus</li>
<li>Procrastination</li>
<li>Lack of motivation</li>
<li>Social anxiety</li>
<li>Difficulty enjoying "normal" things</li>
<li>Relationship struggles</li>
</ul>
<p>—the culprit might be closer than you think.</p>
<p>This isn't about shame. It's about awareness. It's about understanding that you have control over what you feed your brain—and that those choices have real, measurable consequences.</p>
<hr>
<h2>Final Thoughts</h2>
<p>We live in an age of unprecedented stimulation. Our ancestors never had to resist this kind of constant, on-demand hyperstimulation. Our brains simply weren't designed for it.</p>
<p>Understanding this is the first step. The next step is making conscious choices about what you consume—because every time you engage with content that hijacks your reward system, you're casting a vote for the kind of brain you want to have.</p>
<p>Your brain is your greatest asset. Protect it.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[The Fallacy of 'Future-Proofing' Code]]></title>
            <link>https://mustaquenadim.com/blog/the-fallacy-of-future-proofing-code</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/the-fallacy-of-future-proofing-code</guid>
            <pubDate>Tue, 21 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why trying to predict the future is the fastest way to ruin your codebase today, and what you should do instead.]]></description>
            <content:encoded><![CDATA[<p>"Let's make this feature abstract. We'll probably need to support three other types of users in the future."</p>
<p>I have said this. You have said this. We have all said this.</p>
<p>And almost every single time, we were wrong.</p>
<p>The desire to "future-proof" code is deeply ingrained in software engineering. We want to be proactive. We want to show foresight. We want to avoid rewriting our code six months from now.</p>
<p>But in our attempt to predict the future, we usually just make the present unbearable.</p>
<h2>The Cost of YAGNI Violations</h2>
<p>YAGNI stands for "You Aren't Gonna Need It." It is the most frequently ignored principle in programming.</p>
<p>When you future-proof code, you are making a bet. You are betting that you know exactly <em>how</em> the business requirements will evolve.</p>
<p>If you guess right, you save a little bit of refactoring time.</p>
<p>If you guess wrong (and you usually will), you pay a massive penalty:</p>
<ol>
<li><strong>You built the wrong abstraction.</strong> The new requirements don't quite fit the generic interface you designed, so now you have to hack around your own architecture.</li>
<li><strong>You added unnecessary cognitive load.</strong> Every developer who touches that code has to understand an abstraction that isn't actually being used yet.</li>
<li><strong>You wasted time.</strong> Time spent building hypothetical features is time not spent shipping actual value.</li>
</ol>
<h2>The "Delete-ability" Metric</h2>
<p>Instead of optimizing for "how easy is this to extend," we should be optimizing for "how easy is this to delete."</p>
<p>Highly abstracted, heavily coupled, future-proofed code is notoriously difficult to delete because its tentacles reach everywhere.</p>
<p>Simple, concrete, slightly repetitive code is incredibly easy to delete. If a feature fails and the business decides to pivot, you just highlight the block and press Backspace.</p>
<h2>Design for the Present, Refactor for the Future</h2>
<p>The best way to prepare for the future is to write clean, simple code for the present.</p>
<p>When the future actually arrives—when the product manager asks for that second type of user—<em>that</em> is when you refactor. You now have concrete requirements. You aren't guessing anymore. You can build the exact abstraction needed to solve the actual problem in front of you.</p>
<p>Stop trying to predict the future. Your crystal ball is broken. Write code for today.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[The Problem with 'Clean Code' Dogma]]></title>
            <link>https://mustaquenadim.com/blog/problem-with-clean-code-dogma</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/problem-with-clean-code-dogma</guid>
            <pubDate>Mon, 20 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[When the pursuit of abstract perfection actively hurts the maintainability of a codebase.]]></description>
            <content:encoded><![CDATA[<p>"Clean Code" is a fantastic book. Its principles have guided a generation of developers out of the dark ages of 5,000-line god-classes and variable names like <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>x1</span></span></code></span> and <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>dataArray</span></span></code></span>.</p>
<p>But recently, I've noticed a troubling trend: the transformation of these helpful guidelines into rigid, unyielding dogma.</p>
<p>When developers prioritize the <em>appearance</em> of clean code over the <em>reality</em> of readable code, we end up with systems that are beautifully architected but impossible to understand.</p>
<h2>The Fragmented Function</h2>
<p>One of the core tenets of Clean Code is that functions should be small. "Functions should do one thing. They should do it well. They should do it only."</p>
<p>In theory, this is great. In practice, I often see it taken to an extreme. A straightforward 40-line procedural function that reads top-to-bottom gets shredded into eight 5-line functions spread across three different files.</p>
<p>Suddenly, understanding the business logic requires you to maintain a mental stack trace, jumping back and forth between files just to figure out how a user gets authenticated.</p>
<p>Code readability is about context. Sometimes, seeing the whole process in one place (even if it's 50 lines long) is significantly clearer than chasing a trail of meticulously abstracted one-liners.</p>
<h2>The Naming Obsession</h2>
<p>"Choose descriptive and unambiguous names." Again, great advice. But I've reviewed PRs where developers spent 45 minutes debating whether a variable should be <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>userList</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>arrayOfUsers</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>activeUsersCollection</span></span></code></span>, or <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>hydratedUserModels</span></span></code></span>.</p>
<p>If the scope of the variable is only 5 lines long, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>users</span></span></code></span> is fine. Sometimes, within a highly constrained mathematical formula, even <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>i</span></span></code></span> or <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>x</span></span></code></span> is acceptable. The broader the scope, the more descriptive the name needs to be. Context matters.</p>
<h2>The Abstract-Early Anti-Pattern</h2>
<p>The worst offense of Clean Code dogma is premature abstraction.</p>
<p>The DRY (Don't Repeat Yourself) principle is drummed into our heads from day one. As soon as a developer sees the same three lines of code in two places, they feel compelled to extract it into a shared utility function.</p>
<p>But what if those two places are doing things that only <em>happen</em> to be identical right now, but will inevitably diverge in the future?</p>
<p>By tying them together prematurely, you couple two unrelated parts of the system. When one needs to change, the shared utility becomes a convoluted mess of boolean flags and conditional logic.</p>
<p>As Sandi Metz famously said: <em>"Duplication is far cheaper than the wrong abstraction."</em></p>
<h2>Pragmatism > Perfection</h2>
<p>Code is not art meant to be hung in a museum. It is a tool meant to solve problems.</p>
<p>The goal of "clean" code shouldn't be to satisfy a linter or adhere to a checklist in a 15-year-old book. The goal is to ensure that the next person who opens the file (which will probably be you in six months) can understand what it does and change it safely.</p>
<p>Sometimes that means writing a 60-line function. Sometimes it means repeating yourself. And that's okay.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Why You Should Write 'Stupid' Code First]]></title>
            <link>https://mustaquenadim.com/blog/why-you-should-write-stupid-code-first</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/why-you-should-write-stupid-code-first</guid>
            <pubDate>Sun, 19 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The case for writing the dumbest, most straightforward version of a feature before attempting to make it clever or scalable.]]></description>
            <content:encoded><![CDATA[<p>We've all stared at a blank editor, paralyzed by the sheer number of ways to solve a problem.</p>
<p>Should we use a state machine? Is this the right place for the Factory pattern? What if the requirements change next month and we need to support three different types of users?</p>
<p>This paralysis usually comes from trying to write the "smart" code on the first attempt.</p>
<p>The antidote to this paralysis is simple: <strong>Write stupid code first.</strong></p>
<h2>The Anatomy of Stupid Code</h2>
<p>What does "stupid" code look like?</p>
<ul>
<li>It's a single, massive function.</li>
<li>It uses deeply nested <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>if/else</span></span></code></span> statements instead of polymorphism.</li>
<li>It has hardcoded values.</li>
<li>It duplicates logic instead of abstracting it.</li>
<li>It has no regard for performance (within reason).</li>
</ul>
<p>It is, essentially, the code you would write if you only had 15 minutes to solve the problem before your laptop exploded.</p>
<h2>Why Stupid Code Works</h2>
<h3>1. It Defeats the Blank Page</h3>
<p>The hardest part of any task is starting. By giving yourself permission to write terrible code, you lower the barrier to entry. You bypass the critic in your brain and just get words on the screen.</p>
<h3>2. It Clarifies the Problem Domain</h3>
<p>Often, you don't actually understand the problem until you try to solve it. While writing your nested <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>if/else</span></span></code></span> block, you'll suddenly realize, "Oh, I need to account for users who don't have an active subscription."</p>
<p>If you had started by designing an elegant <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>SubscriptionStrategy</span></span></code></span> interface, you might not have discovered that edge case until much later. Stupid code forces you to confront the reality of the business logic immediately.</p>
<h3>3. It Gives You a Baseline</h3>
<p>Once the stupid code works, you have a baseline. You can write tests against it. Now, when you decide to refactor it into that elegant state machine, you can do so with the confidence that you aren't breaking anything.</p>
<h2>The Crucial Second Step: Don't Leave It Stupid</h2>
<p>This is the caveat. "Write stupid code first" is not an excuse to push garbage to production.</p>
<p>It's a two-step process:</p>
<ol>
<li>Make it work (The stupid phase)</li>
<li>Make it right (The refactoring phase)</li>
</ol>
<p>Once the test passes, look at the mess you've created. <em>Now</em> is the time to apply design patterns. <em>Now</em> is the time to extract functions. Because now, you know exactly what the code actually needs to do, rather than what you <em>guessed</em> it needed to do an hour ago.</p>
<p>The next time you're stuck on a feature, don't try to be clever. Just be stupid. Make it work. Then, and only then, make it smart.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[The Danger of 'Just One More Thing']]></title>
            <link>https://mustaquenadim.com/blog/danger-of-just-one-more-thing-scope-creep</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/danger-of-just-one-more-thing-scope-creep</guid>
            <pubDate>Wed, 15 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[How scope creep kills side projects, and a simple framework for actually finishing what you start.]]></description>
            <content:encoded><![CDATA[<p>We've all been there. You have a great idea for a side project. You sketch out the MVP. It's simple, elegant, and doable in a weekend.</p>
<p>You start coding. The core feature takes exactly two days.</p>
<p>But then... <em>the voice</em> whispers.</p>
<p>"You know what would be cool? If users could also log in with GitHub."
"Actually, I should probably add dark mode before I launch."
"Wait, if I'm doing dark mode, I should build a full theming engine."
"You know what? I should rewrite the backend in Rust. It'll be faster."</p>
<p>Six months later, the project is abandoned in a dusty folder on your desktop, completely un-shipped.</p>
<p>This is the silent killer of developers: <strong>The "Just One More Thing" syndrome.</strong></p>
<h2>Why Scope Creep Happens</h2>
<p>Scope creep isn't usually driven by bad intentions. It's driven by enthusiasm and perfectionism.</p>
<p>When you're building something for yourself, you are the product manager, the designer, and the lead engineer. There is no one to say "no." Every cool idea feels essential. Every minor polish feels like a blocker to launch.</p>
<p>The problem is that motivation has a half-life. If you don't ship <em>something</em> quickly, the friction of maintaining an increasingly complex, unlaunched codebase eventually outweighs the excitement of the original idea.</p>
<h2>The "Ship or Delete" Framework</h2>
<p>To combat this, I started using a brutal but effective framework for my side projects. I call it "Ship or Delete."</p>
<h3>1. The Concrete MVP</h3>
<p>Before writing a single line of code, write down exactly what the MVP is. It must be painful to read. It must exclude features you love. Write it in a <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>TODO.md</span></span></code></span> file in the root of the project.</p>
<h3>2. The Launch Date</h3>
<p>Pick a launch date. Not "when it's ready." A specific date on the calendar. If the MVP isn't done by that date, you have to aggressively cut scope to hit it.</p>
<h3>3. The "Next Version" Bucket</h3>
<p>Whenever you get a "just one more thing" idea during development, do not build it. Write it down in a <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>V2_IDEAS.md</span></span></code></span> file. This satisfies the brain's need to capture the idea without derailing the current momentum.</p>
<h3>4. Ship It</h3>
<p>When the MVP is done, launch it. It will feel inadequate. You will be embarrassed by the lack of dark mode. Ship it anyway. The feedback you get from real users (or just the satisfaction of having a live URL) will fuel the motivation needed to actually build the things in your <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>V2_IDEAS.md</span></span></code></span> file.</p>
<p>Stop adding "just one more thing." Start shipping.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[The Overlooked Art of Writing Documentation]]></title>
            <link>https://mustaquenadim.com/blog/overlooked-art-of-writing-documentation</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/overlooked-art-of-writing-documentation</guid>
            <pubDate>Tue, 14 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why good documentation is just as important as good code, and how to write it without hating the process.]]></description>
            <content:encoded><![CDATA[<p>Let's be honest: most developers hate writing documentation. We'd rather fix a complex race condition than explain how to install our project.</p>
<p>But code without documentation is like a brilliant engine with no steering wheel. It has immense potential, but no one knows how to drive it.</p>
<h2>The Myth of "Self-Documenting Code"</h2>
<p>"My code is self-documenting" is the most dangerous lie we tell ourselves.</p>
<p>Clean variable names and well-structured functions are fantastic. They tell you <em>what</em> the code does. But they rarely tell you <em>why</em> it does it that way, or <em>how</em> it fits into the larger system.</p>
<p>Why did you use a custom sorting algorithm here instead of the built-in one? Oh, right, because of that weird edge case with Unicode characters that crashed production last year. The code doesn't explain that. The documentation does.</p>
<h2>What Makes Good Documentation?</h2>
<p>Good documentation isn't about writing a novel. It's about answering the right questions at the right time.</p>
<ol>
<li><strong>The README:</strong> This is the front door. What is this project? How do I get it running locally? Where do I look if something breaks? If your README is just the default output of <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>create-react-app</span></span></code></span>, you're failing your future self.</li>
<li><strong>Architecture Decisions (ADRs):</strong> When you make a big choice (e.g., "We chose Next.js over plain React"), write down why. Record the alternatives considered and the reasons they were rejected. This prevents the same debates from happening six months later.</li>
<li><strong>Inline Comments for the "Why":</strong> Reserve inline comments for explaining the bizarre, the unintuitive, and the workarounds. If a piece of code looks wrong but is actually right, document <em>why</em>.</li>
</ol>
<h2>Documentation as a Developer Tool</h2>
<p>Writing documentation forces you to think about your code from the user's perspective. I've frequently found bugs in my own APIs just by trying to write down how to use them.</p>
<p>If it takes a paragraph to explain what a simple function does, the function is probably too complex. Documentation acts as a mirror, reflecting the quality of your design.</p>
<h2>Start Small</h2>
<p>You don't need a comprehensive Wiki on day one. Start by updating the README. Write one ADR for your next major technical decision. Add a comment explaining that weird regex.</p>
<p>Treat documentation not as an afterthought, but as an integral part of the development process. Your future self—and your teammates—will thank you.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Why I Stopped Using Breakpoints (Most of the Time)]]></title>
            <link>https://mustaquenadim.com/blog/why-i-stopped-using-breakpoints</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/why-i-stopped-using-breakpoints</guid>
            <pubDate>Sun, 12 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[How 'console.log' debugging and unit tests can actually be faster and more effective than traditional step-through debuggers.]]></description>
            <content:encoded><![CDATA[<p>There is a divide in the developer world. On one side: the debugger purists who insist you must use breakpoints, watch variables, and step through code line by line. On the other side: the chaos monkeys typing <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>console.log("here")</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>console.log("here 2")</span></span></code></span>, and <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>console.log(wtf_is_this)</span></span></code></span>.</p>
<p>For years, I felt guilty about belonging to the second group. But recently, I stopped apologizing for it. Because for a large percentage of problems, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>console.log</span></span></code></span> is actually better.</p>
<h2>The Problem with the Debugger</h2>
<p>Traditional debuggers are powerful, but they have a few massive drawbacks:</p>
<ol>
<li><strong>Context Collapse:</strong> When you pause execution, the application state is frozen. This is great for a single moment in time, but terrible for understanding <em>flow</em>. How did this state evolve over the last 10 frames? A debugger gives you a snapshot; logs give you a timeline.</li>
<li><strong>Setup Friction:</strong> Setting up a debugger for a complex full-stack app (frontend, backend, database, maybe a queue) is often more painful than fixing the bug itself.</li>
<li><strong>The "Step Over" Trap:</strong> How many times have you accidentally stepped <em>over</em> the function you needed to step <em>into</em>, forcing you to restart the whole multi-minute reproduction process?</li>
</ol>
<h2>When Logging Wins</h2>
<p><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>console.log</span></span></code></span> (or <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>console.table</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>console.trace</span></span></code></span>) excels when you need to understand the sequence of events.</p>
<p>If a React component is re-rendering 15 times, a breakpoint will drive you insane. You have to hit "play" 15 times, trying to keep the differences in your head.</p>
<p>A well-placed <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>console.log('Render', { props, state })</span></span></code></span> lets you look at the console and instantly see the timeline. You can spot the exact render where <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>props.user</span></span></code></span> suddenly turned into <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>undefined</span></span></code></span>.</p>
<h2>The Real Alternative: Write a Test</h2>
<p>When <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>console.log</span></span></code></span> isn't enough, my next step still isn't usually the debugger. It's a unit test.</p>
<p>If a pure function is returning the wrong output, don't spin up the whole app and click through the UI to trigger it. Write a test case that passes the exact inputs causing the failure. Now you have a reproducible, isolated environment.</p>
<p>And yes, <em>sometimes</em> inside that test, I will finally pull out the debugger.</p>
<h2>The Verdict</h2>
<p>Debuggers are essential for tracking down memory leaks, complex asynchronous deadlocks, or deeply nested library code where logging isn't an option.</p>
<p>But for your day-to-day work? Don't let the purists shame you. <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>console.log("here")</span></span></code></span> is a perfectly valid tool. Just remember to take them out before you commit.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[The Art of Writing Good Commit Messages]]></title>
            <link>https://mustaquenadim.com/blog/the-art-of-writing-good-commit-messages</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/the-art-of-writing-good-commit-messages</guid>
            <pubDate>Sat, 11 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why your commit messages matter more than you think, and a simple framework for writing them better.]]></description>
            <content:encoded><![CDATA[<p>I used to treat Git commits like save points in a video game.</p>
<p>My git log looked something like this:</p>
<ul>
<li><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>fixed bug</span></span></code></span></li>
<li><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>update</span></span></code></span></li>
<li><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>WIP</span></span></code></span></li>
<li><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>finally works</span></span></code></span></li>
<li><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>asdfghjkl</span></span></code></span></li>
</ul>
<p>Then, I joined a team where I had to read <em>other people’s</em> code to figure out why a system broke at 2 AM. That’s when I realized: <strong>commit messages aren’t for you today. They’re for you (and your team) in 6 months.</strong></p>
<h2>Why Commit Messages Matter</h2>
<p>Code tells you <em>how</em> something is done. A good commit message tells you <em>why</em> it was done.</p>
<p>When you’re tracking down a bug using <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>git blame</span></span></code></span>, seeing a commit message that says <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>update styles</span></span></code></span> is useless. Seeing <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>fix: align header button to match new design spec (issue #42)</span></span></code></span> gives you context, intent, and a breadcrumb trail.</p>
<h2>A Simple Framework for Better Commits</h2>
<p>You don't need a heavy, bureaucratic process. Just follow the <strong>Conventional Commits</strong> format. It takes zero extra time once you're used to it, and it makes scanning logs a breeze.</p>
<h3>1. The Prefix (The "What")</h3>
<p>Start every commit with a type. This forces you to categorize what you actually did.</p>
<ul>
<li><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>feat:</span></span></code></span> (New feature)</li>
<li><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>fix:</span></span></code></span> (Bug fix)</li>
<li><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>docs:</span></span></code></span> (Documentation changes)</li>
<li><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>style:</span></span></code></span> (Formatting, missing semi-colons, etc.)</li>
<li><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>refactor:</span></span></code></span> (Code change that neither fixes a bug nor adds a feature)</li>
<li><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>test:</span></span></code></span> (Adding missing tests)</li>
<li><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>chore:</span></span></code></span> (Updating build tasks, package manager configs, etc.)</li>
</ul>
<h3>2. The Subject (The "Why")</h3>
<p>Write a concise, imperative sentence. Imagine you are completing the sentence: <em>"If applied, this commit will..."</em></p>
<ul>
<li>❌ <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>added login button</span></span></code></span> (Past tense)</li>
<li>❌ <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>login button</span></span></code></span> (Not a sentence)</li>
<li>✅ <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>feat: add login button to navigation header</span></span></code></span> (Imperative, clear)</li>
</ul>
<h3>3. The Body (The "Context") - Optional but powerful</h3>
<p>If the change is complex, leave a blank line after the subject and explain <em>why</em> this change was made. What was the problem? What approach did you take? What edge cases did you consider?</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="text" data-theme="github-dark-dimmed"><code data-language="text" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span>fix: resolve race condition in user authentication</span></span>
<span data-line=""> </span>
<span data-line=""><span>The auth token was occasionally being cleared before the redirect </span></span>
<span data-line=""><span>completed on slow connections. Moved the token clearance to the </span></span>
<span data-line=""><span>unmount lifecycle of the login component.</span></span>
<span data-line=""> </span>
<span data-line=""><span>Fixes #123</span></span></code></pre></figure>
<h2>The Atomic Commit Rule</h2>
<p>The secret to good commit messages is writing good commits. <strong>Make atomic commits.</strong></p>
<p>A commit should do <em>one</em> thing. If you find yourself writing <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>feat: add login and fix CSS on pricing page and update README</span></span></code></span>, you should have made three commits.</p>
<h2>The Payoff</h2>
<p>Writing good commit messages feels like eating your vegetables at first. It takes a little discipline. But the first time you use <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>git log</span></span></code></span> to instantly understand why a weird architectural decision was made two years ago, you'll never go back to <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>WIP</span></span></code></span> again.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Developer Productivity: Why I Stopped Chasing the Perfect Setup]]></title>
            <link>https://mustaquenadim.com/blog/stop-chasing-perfect-developer-setup</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/stop-chasing-perfect-developer-setup</guid>
            <pubDate>Fri, 10 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[We've all been there: spending hours tweaking dotfiles, themes, and extensions instead of coding. Here's why the 'perfect' setup is a productivity trap.]]></description>
            <content:encoded><![CDATA[<p>Confession time: I used to spend more time customizing my terminal than actually using it.</p>
<p>If there was a new font with ligatures, a slightly better dark theme, or a VS Code extension that promised to save me 0.5 seconds a day, I was installing it. I maintained my dotfiles like they were a production database.</p>
<p>Then one day, I had to work from a borrowed laptop for a week.</p>
<p>At first, I panicked. No custom aliases? No hyper-optimized window manager? Default terminal colors? It felt like trying to code with oven mitts on.</p>
<p>But a funny thing happened: <strong>I shipped more that week than I had in the previous month.</strong></p>
<h2>The Illusion of Productivity</h2>
<p>Chasing the "perfect" developer setup is a trap. It feels like work. It <em>looks</em> like work. You’re configuring things, reading documentation, optimizing workflows.</p>
<p>But it’s a distraction. It's procrastination disguised as optimization.</p>
<p>We tweak our tools because it gives us a false sense of control and accomplishment, especially when the actual code we need to write is difficult, ambiguous, or intimidating. It's much easier to configure a new Neovim plugin than it is to debug a flaky race condition in your React app.</p>
<h2>The "Good Enough" Philosophy</h2>
<p>These days, my setup is aggressively boring.</p>
<p>I use the defaults for almost everything. If I switch machines, I can be up and running in 10 minutes. I still use a few essential extensions, but the bar for adding something new to my workflow is incredibly high.</p>
<p>If a tool doesn't solve an immediate, painful problem that I experience <em>daily</em>, it doesn't get installed.</p>
<h2>What Actually Matters</h2>
<p>The hard truth about productivity is that it doesn't come from your tools. It comes from:</p>
<ol>
<li><strong>Clarity:</strong> Knowing exactly what you need to build next.</li>
<li><strong>Focus:</strong> The ability to sit down and work on that one thing without checking your phone or switching tabs.</li>
<li><strong>Momentum:</strong> Getting small wins early in your day to build confidence.</li>
</ol>
<p>Your editor is just a text box. Your terminal is just a prompt.</p>
<p>Stop optimizing the text box. Start optimizing your focus. You might be surprised at how fast you can move when you stop trying to go faster.</p>
<hr>
<p><strong>The takeaway:</strong> The next time you feel the urge to spend an hour tweaking your theme or trying a new terminal emulator, ask yourself: <em>What am I avoiding right now?</em> Open the file, write the ugly code, and refine it later.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Type Safety in TypeScript: When Less is More]]></title>
            <link>https://mustaquenadim.com/blog/typescript-type-safety-less-is-more</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/typescript-type-safety-less-is-more</guid>
            <pubDate>Thu, 09 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Finding the sweet spot between strictness and pragmatism in TypeScript. Why over-engineering types kills productivity.]]></description>
            <content:encoded><![CDATA[<p>I spent yesterday refactoring a React component, and I realized something: <strong>the most rigid type definitions aren't always the best ones</strong>.</p>
<h2>The Type Trap</h2>
<p>You know the pattern. Someone writes a type like this:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="typescript" data-theme="github-dark-dimmed"><code data-language="typescript" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F47067">type</span><span style="color:#F69D50"> UserResponse</span><span style="color:#F47067"> =</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#F69D50">  data</span><span style="color:#F47067">:</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#F69D50">    user</span><span style="color:#F47067">:</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#F69D50">      id</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> string</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">      profile</span><span style="color:#F47067">:</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#F69D50">        name</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> string</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">        email</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> string</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">        preferences</span><span style="color:#F47067">:</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#F69D50">          notifications</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> boolean</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">          theme</span><span style="color:#F47067">:</span><span style="color:#96D0FF"> 'light'</span><span style="color:#F47067"> |</span><span style="color:#96D0FF"> 'dark'</span><span style="color:#F47067"> |</span><span style="color:#96D0FF"> 'auto'</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">          language</span><span style="color:#F47067">:</span><span style="color:#96D0FF"> 'en'</span><span style="color:#F47067"> |</span><span style="color:#96D0FF"> 'es'</span><span style="color:#F47067"> |</span><span style="color:#96D0FF"> 'fr'</span><span style="color:#F47067"> |</span><span style="color:#96D0FF"> 'de'</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#ADBAC7">        };</span></span>
<span data-line=""><span style="color:#ADBAC7">      };</span></span>
<span data-line=""><span style="color:#ADBAC7">    };</span></span>
<span data-line=""><span style="color:#ADBAC7">  };</span></span>
<span data-line=""><span style="color:#F69D50">  meta</span><span style="color:#F47067">:</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#F69D50">    timestamp</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> number</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">    requestId</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> string</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#ADBAC7">  };</span></span>
<span data-line=""><span style="color:#ADBAC7">};</span></span></code></pre></figure>
<p>Then three months later, the API adds a new field. You update the type. Then it deprecates one. Update again. Before you know it, you're spending more time massaging types than shipping features.</p>
<h2>Type Safety ≠ Overly Strict Typing</h2>
<p>Here's the thing: <strong>type safety is about catching real bugs, not about achieving type perfection</strong>.</p>
<p>Real bugs are things like:</p>
<ul>
<li>Calling <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>.toUpperCase()</span></span></code></span> on something that might be <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>null</span></span></code></span></li>
<li>Passing a string where a number is expected</li>
<li>Accessing properties that don't exist on an object</li>
</ul>
<p>Real bugs are NOT:</p>
<ul>
<li>A field that <em>could</em> change in the API but probably won't</li>
<li>Deeply nested objects that might have optional properties at the leaf level</li>
<li>Discriminated unions that cover 99% of cases but not that one edge case from 2019</li>
</ul>
<h2>What I Actually Do Now</h2>
<p>I use a pragmatic approach: <strong>types should be as strict as necessary, but no stricter</strong>.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="typescript" data-theme="github-dark-dimmed"><code data-language="typescript" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// ❌ Over-engineered</span></span>
<span data-line=""><span style="color:#F47067">type</span><span style="color:#F69D50"> StrictUser</span><span style="color:#F47067"> =</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#F69D50">  id</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> string</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">  profile</span><span style="color:#F47067">:</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#F69D50">    name</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> string</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">    email</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> string</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">    preferences</span><span style="color:#F47067">:</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#F69D50">      notifications</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> boolean</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">      theme</span><span style="color:#F47067">:</span><span style="color:#96D0FF"> 'light'</span><span style="color:#F47067"> |</span><span style="color:#96D0FF"> 'dark'</span><span style="color:#F47067"> |</span><span style="color:#96D0FF"> 'auto'</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#ADBAC7">    };</span></span>
<span data-line=""><span style="color:#ADBAC7">  };</span></span>
<span data-line=""><span style="color:#ADBAC7">};</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#768390">// ✅ Pragmatic</span></span>
<span data-line=""><span style="color:#F47067">type</span><span style="color:#F69D50"> User</span><span style="color:#F47067"> =</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#F69D50">  id</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> string</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">  name</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> string</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">  email</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> string</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">  preferences</span><span style="color:#F47067">?:</span><span style="color:#F69D50"> Record</span><span style="color:#ADBAC7">&#x3C;</span><span style="color:#6CB6FF">string</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">unknown</span><span style="color:#ADBAC7">>;</span></span>
<span data-line=""><span style="color:#ADBAC7">};</span></span></code></pre></figure>
<p>The second one:</p>
<ul>
<li>Catches the important stuff (missing <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>id</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>name</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>email</span></span></code></span>)</li>
<li>Lets you iterate on <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>preferences</span></span></code></span> without constant type updates</li>
<li>Still gives you autocomplete for known fields</li>
<li>Isn't a maintenance burden</li>
</ul>
<h2>When Do You Actually Need Strict Types?</h2>
<p>Strict types matter in specific places:</p>
<ol>
<li><strong>Public API contracts</strong> — If you're shipping a library, your types are part of your contract. Make them strict.</li>
<li><strong>Critical business logic</strong> — If a single field affects payment, billing, or security, nail it down.</li>
<li><strong>Form validation</strong> — Where precision matters, types should reflect that.</li>
<li><strong>Internal data transforms</strong> — Within a utility, be strict to catch transform bugs.</li>
</ol>
<p>But for most application code? <strong>Strict types are a luxury you can't always afford.</strong></p>
<h2>The Real Win</h2>
<p>TypeScript's magic isn't that it catches everything. It's that it catches <em>enough</em> without getting in your way.</p>
<p>Every hour you spend overthinking your types is an hour you're not:</p>
<ul>
<li>Building features</li>
<li>Talking to users</li>
<li>Fixing real bugs</li>
<li>Learning something new</li>
</ul>
<p>I'd rather ship a feature with <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>Record&#x3C;string, unknown></span></span></code></span> in one place and zero production bugs than spend three days perfecting the type and shipping two weeks late.</p>
<hr>
<p><strong>The takeaway:</strong> Type safety is a tool for confidence, not a sport for perfectionism. Use it where it matters. Be pragmatic elsewhere. Ship.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Finding Focus in a Noisy World: A Developer's Perspective]]></title>
            <link>https://mustaquenadim.com/blog/finding-focus-in-a-noisy-world</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/finding-focus-in-a-noisy-world</guid>
            <pubDate>Tue, 07 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[How I manage distractions, context-switching, and find deep work as a developer.]]></description>
            <content:encoded><![CDATA[<p>It’s 10 AM. I sit down to write some code. Before my fingers even touch the keyboard, Slack pings. An email notification slides into view. My phone buzzes with a WhatsApp message. And just like that, the "zone" I was trying to get into is shattered.</p>
<p>Sound familiar?</p>
<p>As developers, our work requires immense concentration. We build mental models of complex systems, and keeping those models intact while dealing with a constant barrage of interruptions is, frankly, exhausting.</p>
<p>Context-switching is the enemy of deep work. It’s not just the time it takes to deal with the interruption; it’s the time it takes to rebuild that mental model and get back to where you were. It's a massive cognitive tax.</p>
<p>Lately, I've been trying to be much more intentional about protecting my focus. It’s an ongoing battle, but here are a few things that have been working for me:</p>
<h3>1. The "Do Not Disturb" Shield</h3>
<p>This sounds obvious, but it’s amazing how often we forget to use the tools we have. When I need to tackle a complex problem, everything gets muted. Slack goes on DND, my phone goes face down and on silent. If it’s truly an emergency, someone will call. (Spoiler: It’s almost never an emergency.)</p>
<h3>2. Time Blocking</h3>
<p>Instead of a scattered to-do list, I try to block out specific chunks of time for specific tasks. "10:00 AM - 12:00 PM: Refactor the authentication module." During that block, nothing else exists. It sets a boundary and creates a sense of commitment.</p>
<h3>3. Embracing Asynchronous Communication</h3>
<p>We’ve somehow convinced ourselves that every message needs an immediate reply. It doesn’t. Unless the servers are literally on fire, most things can wait a few hours. I’m trying to treat Slack more like email: checking it in batches rather than treating it like a continuous stream of consciousness.</p>
<h3>4. The "Brain Dump" Document</h3>
<p>Often, what breaks my focus isn’t an external interruption, but an internal one. A random idea for another project, a chore I forgot to do, a sudden realization about a bug. Instead of switching gears to deal with it, I quickly jot it down in a scratchpad file. It gets it out of my head so I can refocus, knowing I won't forget it.</p>
<p>Finding focus isn't about perfectly isolating yourself from the world. It’s about building habits and systems that allow you to engage with the noise on your own terms. It’s a messy process, and I still have days where my attention is completely fractured, but the days where I manage to protect that deep work are the days I feel the most fulfilled as a developer.</p>
<p>How do you protect your focus? I'd love to hear what works for you.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Finding Focus in a Distracted World]]></title>
            <link>https://mustaquenadim.com/blog/finding-focus-in-a-distracted-world</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/finding-focus-in-a-distracted-world</guid>
            <pubDate>Mon, 06 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Practical techniques for developer productivity and deep work when everything is demanding your attention.]]></description>
            <content:encoded><![CDATA[<p>As developers, our most valuable asset isn't our knowledge of the latest framework—it's our ability to maintain deep focus. Yet, we work in environments perfectly engineered to destroy it. Slack notifications, PR reviews, email pings, and the infinite scroll of social media constantly fracture our attention.</p>
<p>Over the past year, I've realized that trying to rely on sheer willpower isn't enough. Willpower depletes. You need systems.</p>
<p>Here are a few practical shifts that actually worked for me:</p>
<p><strong>1. The "First Hour" Rule</strong>
The first hour of my workday is sacred. No Slack, no email, no checking stats. It's dedicated entirely to the most complex coding task on my plate. If you start your day reactive (replying to others), you spend the rest of the day trying to catch up to your own priorities. Start proactive.</p>
<p><strong>2. Asynchronous > Synchronous</strong>
Whenever possible, push communication to async channels. A quick sync call often derails 30 minutes of focus context on either side of the call itself. Write good documentation, leave detailed PR descriptions, and normalize taking a few hours to respond to non-urgent messages.</p>
<p><strong>3. Environment Design</strong>
Your environment shapes your behavior. I physically remove my phone from my desk during deep work blocks. I use apps that aggressively block distracting websites. If the distraction requires effort to access, you're much less likely to indulge it out of pure habit.</p>
<p>Focus isn't about working harder; it's about protecting the conditions where good work happens. What's one distraction you can eliminate from your environment today?</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Why Your AI Workflows Keep Breaking (And How to Fix It)]]></title>
            <link>https://mustaquenadim.com/blog/ai-workflows-reliability</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/ai-workflows-reliability</guid>
            <pubDate>Sun, 05 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Automation is fragile. Here's how to build AI workflows that don't fall apart.]]></description>
            <content:encoded><![CDATA[<p>You build something clever with Claude or GPT. It works beautifully for a day. Then... it doesn't.</p>
<p>An edge case you didn't anticipate. The model behaves differently than it did last week. The API times out. Suddenly your "automated" workflow is more work than doing it manually.</p>
<p>I've been there. A lot.</p>
<h2>Why Automation Is Fragile</h2>
<p>AI workflows are fundamentally different from traditional code. They don't fail the same way:</p>
<ol>
<li>
<p><strong>Model outputs are non-deterministic</strong> — You prompt it the same way, and sometimes you get gold. Sometimes you get nonsense. This isn't a bug; it's the nature of probabilistic systems.</p>
</li>
<li>
<p><strong>Edge cases multiply</strong> — Traditional code breaks in predictable ways. AI breaks in creative new ways you didn't imagine. A model might refuse a request that's perfectly safe, or ignore instructions that worked yesterday.</p>
</li>
<li>
<p><strong>Dependencies are invisible</strong> — Your workflow depends on API reliability, rate limits, model behavior, and token limits. When any of these change, everything breaks silently.</p>
</li>
</ol>
<h2>How to Build Workflows That Don't Fall Apart</h2>
<p><strong>1. Plan for failure</strong></p>
<p>Not every task needs to run to completion. Some things need human review. Build checkpoints:</p>
<ul>
<li>Does the AI output make sense? (Have a human check before acting on it)</li>
<li>Did the API succeed? (Retry with exponential backoff, then escalate)</li>
<li>Is this output actually useful? (Validate against expected patterns, not just "is it not null?")</li>
</ul>
<p><strong>2. Use structured outputs</strong></p>
<p>Don't ask the model to write free-form text and parse it. Use JSON modes or structured responses. The difference is night and day.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="plaintext" data-theme="github-dark-dimmed"><code data-language="plaintext" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span>Bad: "Write me a list of tasks"</span></span>
<span data-line=""><span>Good: "Return a JSON array with task objects: {name: string, priority: 'high'|'medium'|'low'}"</span></span></code></pre></figure>
<p><strong>3. Build feedback loops</strong></p>
<ul>
<li>Track what worked and what didn't</li>
<li>Log the inputs and outputs (sanitized, for privacy)</li>
<li>Watch for pattern failures ("this type of request always fails")</li>
<li>Update your prompts based on what you learn</li>
</ul>
<p><strong>4. Fail gracefully</strong></p>
<p>When something breaks, have a fallback:</p>
<ul>
<li>Queue it for manual review</li>
<li>Send a notification to a human</li>
<li>Retry with a different approach (different prompt, different model)</li>
<li>Don't silently do the wrong thing</li>
</ul>
<p><strong>5. Test in isolation</strong></p>
<p>Before you integrate an AI task into a larger workflow, verify it works:</p>
<ul>
<li>Run it 10 times. Do you get consistent outputs?</li>
<li>Try edge cases. What breaks it?</li>
<li>Check the cost. Is this expensive at scale?</li>
</ul>
<h2>The Real Insight</h2>
<p>AI workflows aren't revolutionary because they automate everything. They're useful because they handle the <em>boring</em> parts faster than a human, and they escalate the <em>tricky</em> parts intelligently.</p>
<p>The workflows that break are the ones that assume the AI will "just work." The ones that succeed have humans in the loop, structured expectations, and graceful degradation.</p>
<p>Automation that requires zero maintenance doesn't exist. But automation that requires <em>predictable, minimal</em> maintenance? That's absolutely achievable.</p>
<hr>
<p><em>What's your favorite (or most painful) AI automation story? I'd love to hear what's worked and what's burnt you.</em></p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[The React Suspense Revolution: Why Async Component Rendering Changes Everything]]></title>
            <link>https://mustaquenadim.com/blog/react-suspense-guide</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/react-suspense-guide</guid>
            <pubDate>Sun, 05 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[React Suspense felt like science fiction. Now it's real. Here's how it's changing the way I build components—and why you should care.]]></description>
            <content:encoded><![CDATA[<h1>The React Suspense Revolution: Why Async Component Rendering Changes Everything</h1>
<p>For years, we've been fighting with loading states. A component needs data. While it's fetching, you show a spinner. The data arrives. You show the component. It's worked. But it's clunky.</p>
<p>Then Suspense came along and whispered a dangerous question: <em>What if the component just... waited?</em></p>
<h2>The Old Way (Still Works, But It's Exhausting)</h2>
<p>Every React developer knows this pattern:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F47067">const</span><span style="color:#ADBAC7"> [</span><span style="color:#6CB6FF">data</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">setData</span><span style="color:#ADBAC7">] </span><span style="color:#F47067">=</span><span style="color:#DCBDFB"> useState</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">null</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#F47067">const</span><span style="color:#ADBAC7"> [</span><span style="color:#6CB6FF">loading</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">setLoading</span><span style="color:#ADBAC7">] </span><span style="color:#F47067">=</span><span style="color:#DCBDFB"> useState</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">true</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#F47067">const</span><span style="color:#ADBAC7"> [</span><span style="color:#6CB6FF">error</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">setError</span><span style="color:#ADBAC7">] </span><span style="color:#F47067">=</span><span style="color:#DCBDFB"> useState</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">null</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#DCBDFB">useEffect</span><span style="color:#ADBAC7">(() </span><span style="color:#F47067">=></span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#DCBDFB">  fetchData</span><span style="color:#ADBAC7">()</span></span>
<span data-line=""><span style="color:#ADBAC7">    .</span><span style="color:#DCBDFB">then</span><span style="color:#ADBAC7">(setData)</span></span>
<span data-line=""><span style="color:#ADBAC7">    .</span><span style="color:#DCBDFB">catch</span><span style="color:#ADBAC7">(setError)</span></span>
<span data-line=""><span style="color:#ADBAC7">    .</span><span style="color:#DCBDFB">finally</span><span style="color:#ADBAC7">(() </span><span style="color:#F47067">=></span><span style="color:#DCBDFB"> setLoading</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">false</span><span style="color:#ADBAC7">));</span></span>
<span data-line=""><span style="color:#ADBAC7">}, []);</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">if</span><span style="color:#ADBAC7"> (loading) </span><span style="color:#F47067">return</span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">Spinner</span><span style="color:#ADBAC7"> />;</span></span>
<span data-line=""><span style="color:#F47067">if</span><span style="color:#ADBAC7"> (error) </span><span style="color:#F47067">return</span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">ErrorBoundary</span><span style="color:#6CB6FF"> error</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">error</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> />;</span></span>
<span data-line=""><span style="color:#F47067">return</span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">YourComponent</span><span style="color:#6CB6FF"> data</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">data</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> />;</span></span></code></pre></figure>
<p>It works. But look at the cognitive load: three state variables, conditional rendering, error handling, cleanup. Multiply that across a dozen components and your codebase becomes a state management maze.</p>
<p>I built an entire dashboard like this last year. By component forty, I was copy-pasting state logic like a robot. It worked. But it didn't feel <em>right</em>.</p>
<h2>Enter Suspense</h2>
<p>Suspense lets you wrap async operations and handle loading/error states <em>declaratively, at the tree level</em>. Instead of managing state in every component, you define boundaries.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">Suspense</span><span style="color:#6CB6FF"> fallback</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">Spinner</span><span style="color:#ADBAC7"> /></span><span style="color:#F47067">}</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  &#x3C;</span><span style="color:#8DDB8C">AsyncComponent</span><span style="color:#ADBAC7"> /></span></span>
<span data-line=""><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">Suspense</span><span style="color:#ADBAC7">></span></span></code></pre></figure>
<p>The component itself just... fetches and renders. No state management. No conditional branching. The Suspense boundary catches the "promise" and shows the fallback until the data is ready.</p>
<h3>Why This Matters</h3>
<p><strong>For components:</strong> Less boilerplate. Your component code is simpler and focuses on rendering, not state gymnastics.</p>
<p><strong>For UX:</strong> You can define loading states at the right granularity—not every component reinventing spinners.</p>
<p><strong>For data fetching libraries:</strong> Frameworks like Next.js App Router and libraries like TanStack Query now have first-class Suspense support. The async/await dream is becoming real.</p>
<h2>Real Talk: The Gotchas</h2>
<p>I've been experimenting with Suspense in production for the last few months. It's powerful, but there's a learning curve:</p>
<p><strong>1. You need a library that supports it.</strong> Suspense alone doesn't handle data fetching—you need something like:</p>
<ul>
<li>Next.js Server Components</li>
<li>Remix loaders</li>
<li>TanStack Query with Suspense mode</li>
<li>Custom <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>use()</span></span></code></span> hook with Promise caching</li>
</ul>
<p>Plain <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>fetch()</span></span></code></span> and <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useState()</span></span></code></span> won't cut it. You need a <em>source</em> that throws promises.</p>
<p><strong>2. Error handling changes.</strong> Suspense handles loading, but you need an Error Boundary for errors. Not a <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>try/catch</span></span></code></span>—an actual Error Boundary component wrapping your Suspense tree.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">ErrorBoundary</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  &#x3C;</span><span style="color:#8DDB8C">Suspense</span><span style="color:#6CB6FF"> fallback</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">Spinner</span><span style="color:#ADBAC7"> /></span><span style="color:#F47067">}</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;</span><span style="color:#8DDB8C">YourComponent</span><span style="color:#ADBAC7"> /></span></span>
<span data-line=""><span style="color:#ADBAC7">  &#x3C;/</span><span style="color:#8DDB8C">Suspense</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">ErrorBoundary</span><span style="color:#ADBAC7">></span></span></code></pre></figure>
<p><strong>3. Waterfalls are still a thing.</strong> If Component A fetches data, then Component B (nested inside A) fetches <em>more</em> data, you're still waiting sequentially. Suspense doesn't magically parallelize—you have to architecture it right.</p>
<h2>The Aha Moment</h2>
<p>Here's where Suspense clicked for me: I was rebuilding a profile page in Next.js with Server Components. Instead of:</p>
<ul>
<li>Fetching user data in the page component</li>
<li>Passing it down to ten child components</li>
<li>Handling loading states at each level</li>
</ul>
<p>I just:</p>
<ul>
<li>Let each component fetch what it needs (suspending independently)</li>
<li>Wrapped logical sections in Suspense boundaries</li>
<li>Showed partial UI as pieces loaded</li>
</ul>
<p>The user saw <em>something</em> instantly. The page felt faster because it <em>was</em> faster—no false waterfalls, just progressive rendering.</p>
<h2>So Should You Use It?</h2>
<p><strong>Yes, if:</strong></p>
<ul>
<li>You're using Next.js, Remix, or another Suspense-compatible framework</li>
<li>You want cleaner component code</li>
<li>You're willing to learn the mental model (it's different from traditional async/await)</li>
</ul>
<p><strong>Maybe later, if:</strong></p>
<ul>
<li>You're on plain React without a data-fetching library that supports Suspense</li>
<li>Your team isn't familiar with Error Boundaries and the Suspense model yet</li>
<li>You need to support older React versions</li>
</ul>
<p><strong>Not yet, if:</strong></p>
<ul>
<li>You're using an older codebase and Suspense requires a major refactor</li>
<li>The learning curve isn't worth the gains <em>right now</em></li>
</ul>
<h2>The Real Win</h2>
<p>Suspense isn't just a technical feature. It's a shift in how we think about async rendering. Instead of treating loading as a <em>component problem</em>, we treat it as a <em>tree problem</em>. The data flow is clearer. The code is simpler. The UX is better.</p>
<p>I still remember the first time I shipped a Suspense-powered page and a user said it "felt fast." Not because the API was faster. But because they saw the UI <em>building</em> in real-time instead of staring at a blank screen.</p>
<p>That's the revolution.</p>
<hr>
<p><strong>What's your experience with Suspense?</strong> Have you shipped it in production, or are you still exploring? I'd love to hear what worked (and what didn't) in your projects.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[React Performance Optimization: The Basics That Actually Matter]]></title>
            <link>https://mustaquenadim.com/blog/react-performance-optimization</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/react-performance-optimization</guid>
            <pubDate>Sat, 04 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Stop overthinking. Here's what actually moves the needle in React performance.]]></description>
            <content:encoded><![CDATA[<p>You know that feeling when you optimize something in React and wonder if anyone actually noticed? Yeah, me too.</p>
<p>Most React performance tips float around the internet as cargo cult advice—people repeat them because they sound smart, not because they've measured the impact. So let me cut through the noise and talk about what <em>actually</em> matters.</p>
<h2>The Real Problem</h2>
<p>React re-renders happen. A lot. And most of them don't cause visual jank. But when they do, it's usually because:</p>
<ol>
<li>
<p><strong>You're computing expensive stuff during render</strong> — This is the biggie. If your render function is doing heavy math, API calls disguised as derived state, or massive object transformations, you're going to feel it.</p>
</li>
<li>
<p><strong>You're not memoizing the right things</strong> — Not <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useMemo</span></span></code></span> on everything. Just the computations that are actually slow and run on every render.</p>
</li>
<li>
<p><strong>Your dependency arrays are wrong</strong> — And you're re-rendering when you shouldn't be.</p>
</li>
</ol>
<h2>What To Actually Do</h2>
<p><strong>1. Profile First, Optimize Second</strong></p>
<p>Open DevTools → Profiler tab. Record a session. <em>See where time is actually spent</em>. I've spent hours optimizing the wrong function before.</p>
<p><strong>2. Use <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useMemo</span></span></code></span> for actual calculations</strong></p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="javascript" data-theme="github-dark-dimmed"><code data-language="javascript" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F47067">const</span><span style="color:#6CB6FF"> expensiveValue</span><span style="color:#F47067"> =</span><span style="color:#DCBDFB"> useMemo</span><span style="color:#ADBAC7">(() </span><span style="color:#F47067">=></span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#768390">  // Do real work here: filtering huge arrays, calculating complex values</span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#DCBDFB"> complexCalculation</span><span style="color:#ADBAC7">(data);</span></span>
<span data-line=""><span style="color:#ADBAC7">}, [data]);</span></span></code></pre></figure>
<p>Not for component definitions. Not for objects that don't change. Just actual computations.</p>
<p><strong>3. Keep your deps arrays tight</strong></p>
<p>This is where most bugs live. A dependency changes unexpectedly, and suddenly you're re-rendering every frame.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="javascript" data-theme="github-dark-dimmed"><code data-language="javascript" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// Bad: deps include everything</span></span>
<span data-line=""><span style="color:#DCBDFB">useEffect</span><span style="color:#ADBAC7">(() </span><span style="color:#F47067">=></span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#DCBDFB">  doSomething</span><span style="color:#ADBAC7">();</span></span>
<span data-line=""><span style="color:#ADBAC7">}, [state, props, user, config, </span><span style="color:#F47067">...</span><span style="color:#ADBAC7">]);</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#768390">// Good: only what actually matters</span></span>
<span data-line=""><span style="color:#DCBDFB">useEffect</span><span style="color:#ADBAC7">(() </span><span style="color:#F47067">=></span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#DCBDFB">  doSomething</span><span style="color:#ADBAC7">();</span></span>
<span data-line=""><span style="color:#ADBAC7">}, [userId]); </span><span style="color:#768390">// just the ID, not the whole user object</span></span></code></pre></figure>
<p><strong>4. Code split. Actually.</strong></p>
<p>If your bundle is 500KB, performance optimization is theater. Split routes, split heavy libraries, use dynamic imports. Your initial load time matters more than micro-optimizations.</p>
<h2>The Meta-Insight</h2>
<p>The fastest code is code that doesn't run. The second fastest is code that runs once and caches the result. Everything else is details.</p>
<p>So before you reach for <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>React.memo</span></span></code></span> or <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useCallback</span></span></code></span>, ask: <em>Do I need this to run at all?</em></p>
<p>Most of the time, the answer will surprise you.</p>
<hr>
<p><em>What's your biggest React performance headache? The stuff that keeps you up at night, not the theoretical stuff.</em></p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[The Problem with Time Blocking (And What to Do Instead)]]></title>
            <link>https://mustaquenadim.com/blog/time-blocking-myth</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/time-blocking-myth</guid>
            <pubDate>Fri, 03 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why rigidly scheduling every minute of your day rarely works for developers, and a more flexible approach to managing focus.]]></description>
            <content:encoded><![CDATA[<p>If you read any productivity blog, you'll eventually come across "time blocking." The advice is simple: schedule every single minute of your day on your calendar. 9:00 AM to 11:00 AM for coding, 11:00 AM to 12:00 PM for emails, 1:00 PM to 2:00 PM for meetings.</p>
<p>In theory, it's brilliant. In practice, especially for software engineering, it often falls apart before lunch.</p>
<h3>The Myth of Predictable Work</h3>
<p>The core issue with rigid time blocking is that it assumes your work takes a predictable amount of time.</p>
<p>But as any developer knows, estimating the time it takes to fix a bug or implement a new feature is notoriously difficult. Sometimes a "quick 30-minute fix" turns into a three-hour rabbit hole because of a bizarre edge case in an external library.</p>
<p>When your 9:00 AM "coding block" inevitably spills over into your 11:00 AM "email block," the entire schedule cascades into failure. You feel like you're constantly behind, playing catch-up against an arbitrary timeline you invented the day before.</p>
<h3>The Maker's Schedule Needs Flexibility</h3>
<p>Paul Graham famously wrote about the "Maker's Schedule, Manager's Schedule." Managers thrive on hourly blocks because their job is a series of distinct tasks and meetings. Makers (like developers) need large, uninterrupted chunks of time to build context and get into flow.</p>
<p>When you artificially slice your day into rigid blocks, you introduce context switching. You might be deep in the zone solving a complex problem, but if your calendar says it's time to check emails, you force a cognitive gear shift. Getting back into that deep flow state later can take 20-30 minutes of wasted effort.</p>
<h3>What to Do Instead: The Priority List</h3>
<p>Instead of scheduling <em>when</em> you'll do things, focus on <em>what</em> you'll do.</p>
<p>Here's the flexible approach that has actually worked for me:</p>
<ol>
<li><strong>The Top Priority:</strong> Every morning, pick <em>one</em> major task. This is the thing that, if completed, makes the day a success.</li>
<li><strong>The "If I Have Time" List:</strong> Pick two or three smaller, secondary tasks.</li>
<li><strong>Protect the Block, Not the Minutes:</strong> Block out 3-4 hours of uninterrupted time on your calendar (usually the morning when you have the most energy). Don't schedule specific tasks within it. Just protect it from meetings.</li>
<li><strong>Work Until It's Done (Or You're Stuck):</strong> During your protected time, start on your Top Priority. Work on it until it's finished, or until you hit a hard roadblock. <em>Then</em> move to the secondary tasks.</li>
</ol>
<p>This approach gives you the structure you need without the guilt of a rigid, failed schedule. You prioritize the most important work, but you give yourself the grace to let tasks take the time they actually need.</p>
<p>Productivity isn't about perfectly Tetris-ing your calendar. It's about consistently making progress on the things that matter.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Stop Over-Optimizing Your React Apps Too Early]]></title>
            <link>https://mustaquenadim.com/blog/stop-over-optimizing-react</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/stop-over-optimizing-react</guid>
            <pubDate>Thu, 02 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why obsessing over useMemo and useCallback from day one is a trap, and when you actually need to worry about performance.]]></description>
            <content:encoded><![CDATA[<p>We've all been there. You're building a new React component, and before you even finish the first render, you're already wrapping every function in <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useCallback</span></span></code></span> and every object in <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useMemo</span></span></code></span>.</p>
<p>You think to yourself: "I'm writing high-performance React code. Look at me go!"</p>
<p>I used to do this. A lot. But recently, I realized that this premature optimization is often a massive waste of time—and sometimes, it even makes your app slower.</p>
<h3>The Illusion of "Free" Performance</h3>
<p>The core misunderstanding is thinking that <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useMemo</span></span></code></span> and <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useCallback</span></span></code></span> are free. They aren't.</p>
<p>React has to do work to check those dependencies on every single render. It has to compare <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>deps[0] === nextDeps[0]</span></span></code></span>. It has to store the memoized value in memory.</p>
<p>If the calculation you're memoizing is simple (like filtering a list of 10 items or concatenating two strings), the overhead of checking the dependencies and running <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useMemo</span></span></code></span> is often <em>more expensive</em> than just re-calculating the value!</p>
<p>You're literally spending performance to save performance. It's like clipping coupons for a penny while paying a dollar for the scissors.</p>
<h3>Readability Matters More Than Micro-Optimizations</h3>
<p>When you wrap everything in hooks, your code becomes incredibly noisy. A simple component turns into a tangled mess of dependency arrays.</p>
<p>This makes your code harder to read, harder to review, and exponentially harder to refactor. Every time you add a new prop or state variable, you have to meticulously update five different dependency arrays, praying you didn't miss one and introduce a stale closure bug.</p>
<h3>When Should You Actually Optimize?</h3>
<p>My new rule of thumb is embarrassingly simple: <strong>Don't optimize until it's noticeably slow.</strong></p>
<p>React is incredibly fast out of the box. For 95% of typical web apps, React's default rendering behavior is perfectly fine.</p>
<p>When you <em>do</em> notice a performance issue (a janky animation, a slow input field, a lagging modal), that's when you pull out the React Profiler.</p>
<ol>
<li><strong>Measure:</strong> Use the Profiler to identify exactly which component is taking too long to render.</li>
<li><strong>Isolate:</strong> Often, the fix isn't <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useMemo</span></span></code></span>. It's moving state <em>down</em> the tree so fewer components re-render, or using <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>children</span></span></code></span> props to avoid re-rendering expensive wrappers.</li>
<li><strong>Memoize:</strong> If you genuinely have an expensive calculation (like sorting a massive array or rendering a complex chart), <em>then</em> apply <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useMemo</span></span></code></span>.</li>
</ol>
<p>Stop trying to be clever. Write simple, readable React code first. Make it work, make it right, and only then, if necessary, make it fast.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[The Reality of Building with LLMs: It's Not Magic, It's Systems]]></title>
            <link>https://mustaquenadim.com/blog/building-with-llms-reality</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/building-with-llms-reality</guid>
            <pubDate>Wed, 01 Apr 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why integrating AI into your app is less about clever prompts and more about boring, old-fashioned software engineering.]]></description>
            <content:encoded><![CDATA[<p>I used to think that building AI features was all about writing the perfect prompt. Just say the right incantation, and the LLM will output exactly what you want, right?</p>
<p>Yeah, no.</p>
<p>After spending the last few months deeply integrating LLMs into real-world workflows, my biggest "aha!" moment has been surprisingly mundane: <strong>building with AI is mostly just traditional systems engineering.</strong></p>
<h3>The Prompt is the Easy Part</h3>
<p>When you first start playing with the OpenAI or Anthropic APIs, you spend hours tweaking prompts. You add "You are a helpful assistant" and "Think step by step." It feels magical.</p>
<p>But when you try to put that into a production app, the magic fades fast.</p>
<p>The LLM will hallucinate. It will ignore your instructions. It will format the JSON wrong 5% of the time. The API will timeout. You'll hit rate limits.</p>
<p>Suddenly, your prompt isn't the bottleneck. The <em>wrapper around the prompt</em> is the bottleneck.</p>
<h3>It's All About Scaffolding</h3>
<p>The actual prompt engineering is maybe 10% of the work. The other 90% is building the scaffolding to make the LLM reliable:</p>
<ol>
<li><strong>Validation &#x26; Retries:</strong> If the LLM returns invalid JSON, you don't throw an error. You catch it, send the error <em>back</em> to the LLM, and tell it to fix it.</li>
<li><strong>Context Assembly:</strong> The LLM is only as smart as the context you give it. Building robust data pipelines to fetch the <em>right</em> user data, format it cleanly, and inject it into the prompt is where the real value lies. (RAG is just a fancy term for this).</li>
<li><strong>Fallbacks:</strong> What happens when the API is down? You need graceful degradation.</li>
<li><strong>State Management:</strong> Tracking the history of a multi-turn conversation or a multi-step agent workflow is pure, boring state management.</li>
</ol>
<h3>Treat LLMs Like Unreliable Interns</h3>
<p>The best mental model I've found is to treat the LLM like an incredibly fast, but easily distracted, intern.</p>
<p>You wouldn't hand an intern a massive, vague task and expect perfection on the first try. You'd break it down into small, isolated steps. You'd give them clear checklists. You'd review their work at every stage.</p>
<p>Building with LLMs is the same. Instead of one massive prompt trying to do everything, chain together smaller, specialized calls. Have one call extract the data, another format it, and a third verify it.</p>
<p>The magic of AI isn't in the model itself. The magic is in the robust, resilient systems we build around it.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[The Silent Speed Killer: Mastering Next.js Caching]]></title>
            <link>https://mustaquenadim.com/blog/mastering-nextjs-caching</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/mastering-nextjs-caching</guid>
            <pubDate>Tue, 31 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why your perfectly optimized Next.js app is still slow, and how to fix it.]]></description>
            <content:encoded><![CDATA[<p>If you've built anything with the Next.js App Router, you've probably hit that moment where your app feels sluggish despite having a lighthouse score of 100. It took me an embarrassingly long time to realize that the culprit was often right under my nose: the caching layer.</p>
<p>Next.js caching is aggressive by default. It assumes you want everything static unless told otherwise. The "aha!" moment for me was realizing I needed to actively manage <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>revalidate</span></span></code></span> times and explicitly define what data changes frequently.</p>
<p>Stop fighting the cache. Instead, map out your data dependencies <em>before</em> writing the component. When does this specific piece of data actually become stale? Once I started defining caching strategies component by component (using <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>next: { revalidate: 3600 }</span></span></code></span> or <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>no-store</span></span></code></span> when necessary), the random sluggishness disappeared.</p>
<p>Performance isn't just about small bundles; it's about predicting when your user needs fresh data versus when yesterday's news will do just fine.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[React Performance Optimization: It's Not About the Bundle]]></title>
            <link>https://mustaquenadim.com/blog/react-performance-optimization-mindset</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/react-performance-optimization-mindset</guid>
            <pubDate>Mon, 30 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[The real performance wins come from understanding *why* your app is slow, not just making it smaller. Here's what I learned the hard way.]]></description>
            <content:encoded><![CDATA[<p>For years, I obsessed over bundle size. Smaller bundle = faster app, right? Then I spent a week debugging a "slow" React app with a tiny bundle and realized my whole mental model was backwards.</p>
<h2>The Aha Moment</h2>
<p>We shipped a major feature with aggressive code-splitting and tree-shaking. Bundle size was down 30%. The app <em>felt</em> slower.</p>
<p>Turns out, we'd optimized for download time but murdered our runtime performance. We were re-rendering entire sections unnecessarily, creating new objects on every render, and the browser was working harder than before.</p>
<p>That's when it clicked: <strong>performance is a pyramid, and bundle size is just the base.</strong></p>
<h2>The Real Performance Pyramid (from bottom up)</h2>
<ol>
<li><strong>Runtime Performance</strong> — How fast does your app <em>run</em> after download?</li>
<li><strong>Render Efficiency</strong> — How smart is React about what to re-render?</li>
<li><strong>Data Fetching</strong> — How much data are you actually asking the network for?</li>
<li><strong>Bundle Size</strong> — How much code is the user downloading?</li>
</ol>
<p>Most of us start at the top and wonder why we're not getting wins.</p>
<h2>What Actually Changed For Us</h2>
<ul>
<li><strong>Memoization (the right way):</strong> Instead of wrapping everything in <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>memo()</span></span></code></span>, we identified which components were expensive and <em>why</em>. Turns out, we had 3 culprits. Three.</li>
<li><strong>Derived state → computed values:</strong> We stopped storing derived data in state and started computing it when needed. Counter-intuitive, but it eliminated a whole class of sync bugs and stale closures.</li>
<li><strong>Query co-location:</strong> Instead of fetching data at the top level, we moved queries closer to where they're actually used. Smaller payloads, faster perceived performance.</li>
</ul>
<h2>The Mindset Shift</h2>
<p>Stop thinking "How do I make this smaller?" and start thinking "Why is this slow?"</p>
<p>Profile first. Measure second. Optimize third. The tools are free:</p>
<ul>
<li>React DevTools Profiler (literally in your browser)</li>
<li>Chrome DevTools Performance tab (underrated)</li>
<li><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>console.time()</span></span></code></span> (criminally simple, criminally effective)</li>
</ul>
<h2>One More Thing</h2>
<p>The best performance optimization I've made isn't in code. It's scheduling renders to happen when the user isn't expecting them (background tasks, idle callbacks, requestIdleCallback). The user doesn't care if your render takes 50ms if it happens while they're not looking.</p>
<p>Modern React with Concurrent Features gets this. Use it.</p>
<hr>
<p><strong>What performance rabbit hole have you gone down? What assumptions did you have to unlearn?</strong></p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[React Context vs Prop Drilling: When to Use Each (and When to Avoid Both)]]></title>
            <link>https://mustaquenadim.com/blog/react-context-vs-prop-drilling</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/react-context-vs-prop-drilling</guid>
            <pubDate>Sun, 29 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[A practical guide to choosing the right state management pattern for your React components—and recognizing when you're overcomplicating things.]]></description>
            <content:encoded><![CDATA[<p>I've seen this happen a hundred times: a React codebase starts clean. Then features pile up. Props flow through five layers of components. Developers panic and reach for Context. Suddenly they've got three Context providers at the root, and changes to any of them re-render the entire app.</p>
<p>Both paths feel like failures. One feels tedious and wrong; the other feels smart but smells bad. Let me talk about what's actually happening and how to make a real choice.</p>
<h2>The Real Problem with Prop Drilling</h2>
<p>Prop drilling isn't inherently evil. What makes it annoying is <strong>intermediate components that don't care about the data</strong>. If a Button component needs to pass <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>theme</span></span></code></span> down to Text, but Button doesn't use <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>theme</span></span></code></span> itself, that's friction. You're using the component as a pipe, not a meaningful abstraction.</p>
<p>The pain points are real:</p>
<ul>
<li>Refactoring becomes brittle (rename a prop and trace it through 10 components)</li>
<li>It's unclear which props matter to which level</li>
<li>New team members struggle to understand the data flow</li>
</ul>
<p>But here's what I learned: <strong>drilling is a signal, not a sentence.</strong> If you're drilling the same thing through 3+ levels, ask why. Maybe:</p>
<ol>
<li>The intermediate component shouldn't exist (flatten the tree)</li>
<li>You're drilling something that should live lower (move state closer to where it's used)</li>
<li>You actually need a shared state mechanism (Context, Redux, Zustand)</li>
</ol>
<h2>When Context Actually Helps</h2>
<p>Context shines when you have <strong>truly global or cross-cutting concerns</strong>:</p>
<ul>
<li>Theme or dark mode toggle</li>
<li>Authenticated user info</li>
<li>Language/locale settings</li>
<li>UI state that affects many distant branches</li>
</ul>
<p>The key: these things change infrequently, and when they do, re-rendering the whole tree is acceptable because the changes aren't granular.</p>
<p>Where Context fails is when you use it for <strong>frequently-changing, feature-specific state</strong>. Every time that context updates, every component reading it re-renders—even if they only use one field. You end up wrapping components in <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useMemo</span></span></code></span> to prevent thrashing, which defeats the purpose.</p>
<p>I made this mistake. I threw a "GlobalState" context around the entire app with product filters, user preferences, UI modals, and notifications all in one object. When the user toggled a filter (which happened every few seconds), the entire app re-rendered. Then I added useMemo everywhere and the code became unreadable.</p>
<h2>A Practical Heuristic</h2>
<p>Ask yourself these questions:</p>
<p><strong>1. Does this data change often?</strong></p>
<ul>
<li>If yes → use local state or a fine-grained state manager (Zustand, Jotai)</li>
<li>If no → Context is fine</li>
</ul>
<p><strong>2. How many components read this?</strong></p>
<ul>
<li>1–2 → pass it as props</li>
<li>3–4 → consider Context or local state in a shared parent</li>
<li>5+ → reach for Context or a state manager</li>
</ul>
<p><strong>3. Is this the only thing in the context?</strong></p>
<ul>
<li>If no, split it → separate concerns into multiple contexts</li>
<li>If yes → you're probably good</li>
</ul>
<p><strong>4. Am I nesting Contexts more than 3 levels deep?</strong></p>
<ul>
<li>If yes → reconsider your structure or switch to a state manager</li>
</ul>
<h2>The Goldilocks Zone</h2>
<p>Here's what worked for me:</p>
<ul>
<li><strong>Local state</strong> for component-specific toggles (expanded/collapsed, form inputs, hover state)</li>
<li><strong>Prop drilling</strong> for 1–2 levels (Button → Text, Page → Card → Header)</li>
<li><strong>Context</strong> for truly global stuff (theme, language, auth status)</li>
<li><strong>Zustand or Jotai</strong> for feature-specific state that's used in multiple branches (filters, form state, UI modals)</li>
</ul>
<p>The weird middle case? If you have state that lives in multiple components but isn't truly global—like a modal that's used in 3 unrelated parts of the app—don't use Context for the whole modal state. Instead:</p>
<ul>
<li>Use Context for "which modal is open?" (boolean flag)</li>
<li>Use local state or a store for the modal's internal data</li>
<li>Pass callbacks or expose actions via the context</li>
</ul>
<h2>A Real Example</h2>
<p>Say you're building a todo app with a sidebar filter panel and a main list. The filter changes every second as the user types. The list depends on the filter.</p>
<p><strong>Bad:</strong> Context with <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>{ filter: string }</span></span></code></span> → any filter change re-renders sidebar + list + buttons</p>
<p><strong>Better:</strong></p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// In a parent component</span></span>
<span data-line=""><span style="color:#F47067">const</span><span style="color:#ADBAC7"> [</span><span style="color:#6CB6FF">filter</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">setFilter</span><span style="color:#ADBAC7">] </span><span style="color:#F47067">=</span><span style="color:#DCBDFB"> useState</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">""</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">FilterPanel</span><span style="color:#6CB6FF"> filter</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">filter</span><span style="color:#F47067">}</span><span style="color:#6CB6FF"> onFilterChange</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">setFilter</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> /></span></span>
<span data-line=""><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">TodoList</span><span style="color:#6CB6FF"> filter</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">filter</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> /></span></span></code></pre></figure>
<p>If 5 components need to read the filter, <em>then</em> you're justified reaching for Context or a store. Not before.</p>
<h2>Honest Assessment</h2>
<p>I've overcomplicated state management more times than I've nailed it. The pattern I've learned: start simple, observe the pain, then choose a tool. Not the other way around.</p>
<p>Prop drilling is annoying but honest—you can see the data flow. Context is powerful but can hide performance issues. Neither is wrong; context matters is <strong>starting with the simplest thing that works and only graduating when you feel real friction.</strong></p>
<p>Try it on your next feature. Drill props for a week. Only reach for Context when you genuinely hate the drilling, not when you <em>think</em> you will.</p>
<p>— Mustaque Nadim</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Focus Techniques for Developers: Small Habits that Make Big Wins]]></title>
            <link>https://mustaquenadim.com/blog/focus-techniques-for-developers</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/focus-techniques-for-developers</guid>
            <pubDate>Sat, 28 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Practical focus and time-management techniques I've actually used as a developer.]]></description>
            <content:encoded><![CDATA[<p>I used to believe that being busy meant being productive. For a long time my days were full of meetings, half-started tasks, and the comforting glow of an inbox that never emptied. The real problem wasn't that I had too much to do — it was that I had no reliable way to protect the time I needed to think.</p>
<p>This post collects a few simple focus techniques I've tried (and kept) over the years. They're not glamorous; they're the small habits that actually survive long weeks and shipping pressure.</p>
<ol>
<li>The 90/30 Rule (not a timer obsession)</li>
</ol>
<p>I aim for a 90-minute focused block followed by a 30-minute break. Why 90 minutes? It fits my natural attention cycle: long enough to do deep work, short enough to stay accountable. The 30-minute break isn't just rest — it's a reset. Walk, make tea, or do something that isn't screen-based.</p>
<ol start="2">
<li>The One-Thing Commitment</li>
</ol>
<p>At the start of a block I write down one concrete deliverable: "Fix X bug", "Ship Y feature's first draft", "Write tests for Z". That tiny commitment anchors the session. If I finish early, I either iterate on the same thing or grab the next one — not scatter.</p>
<ol start="3">
<li>Email and Slack Doorways</li>
</ol>
<p>I close communication apps during focused blocks. For high-context conversations I block a short overlap window (20–30 minutes) to catch up. When I return, I triage: what needs immediate reply, what can wait, and what becomes a quick task.</p>
<ol start="4">
<li>The Two-Minute Rule (for merciless context clearing)</li>
</ol>
<p>If a task takes less than two minutes, do it immediately. It keeps the list short and prevents small frictions from piling up into context-switching debt.</p>
<ol start="5">
<li>Pre-mortems for the day</li>
</ol>
<p>Before lunch I spend 5 minutes imagining what could block my afternoon. If a meeting might derail focus, I reschedule or prep a short agenda. Pre-mortems make interruptions easier to manage because I expected them.</p>
<ol start="6">
<li>Keep a "Parking Lot"</li>
</ol>
<p>When an idea or unrelated bug shows up, I jot it into a parking lot (notes or a simple todo list). The act of writing it down removes the mental anchor so I can return to focus quickly.</p>
<ol start="7">
<li>Practice Rest as an Activity</li>
</ol>
<p>Good rest is active: a short walk, stretching, or a 20-minute nap if the day allows. My most productive afternoons started after a deliberate rest, not after pushing through exhaustion.</p>
<p>A few honest confessions</p>
<ul>
<li>I still fail sometimes. Meetings creep in. Urgent fires happen. The difference is that these techniques make failures easier to recover from.</li>
<li>It's tempting to use timers like a productivity religion. Timers are tools — not badges.</li>
<li>The hardest part is choosing the right number of commitments. Be ruthless about scope.</li>
</ul>
<p>Final note</p>
<p>Focus isn't a single hack. It's a set of tiny choices you make repeatedly: what to start, what to ignore, when to rest. If you can protect one 90-minute session a day and treat the rest as flexible, you'll be surprised how much gets done.</p>
<p>If you try any of this, tell me which one stuck and why — hearing others' edge cases is how I refine my own practice.</p>
<p>— Mustaque Nadim</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Why Your Next.js Data Fetching Might Be Slower Than You Think]]></title>
            <link>https://mustaquenadim.com/blog/nextjs-data-fetching-performance</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/nextjs-data-fetching-performance</guid>
            <pubDate>Fri, 27 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Common mistakes that tank your Next.js performance: waterfalls, missing cache headers, and routes that should be static. Here's how to fix them.]]></description>
            <content:encoded><![CDATA[<p>I shipped a page last month that <em>felt</em> fast locally but crawled in production. Turns out I was making three sequential API calls when I could've made one. Then I wasn't caching. Then I was re-validating static content every request.</p>
<p>Sound familiar? Here's what I learned.</p>
<h2>The waterfall trap</h2>
<p>You fetch User → then fetch Posts → then fetch Comments. Each waits for the previous one to finish. Three API calls that could run in parallel are now running serially. That's a waterfall.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="js" data-theme="github-dark-dimmed"><code data-language="js" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// ❌ Serial fetches = slow</span></span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> default</span><span style="color:#F47067"> async</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> Page</span><span style="color:#F69D50">({ params }) </span><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> user</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#DCBDFB"> fetch</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">`/api/users/${</span><span style="color:#ADBAC7">params</span><span style="color:#96D0FF">.</span><span style="color:#ADBAC7">id</span><span style="color:#96D0FF">}`</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> posts</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#DCBDFB"> fetch</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">`/api/posts?userId=${</span><span style="color:#ADBAC7">user</span><span style="color:#96D0FF">.</span><span style="color:#ADBAC7">id</span><span style="color:#96D0FF">}`</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> comments</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#DCBDFB"> fetch</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">`/api/comments?postId=${</span><span style="color:#ADBAC7">posts</span><span style="color:#96D0FF">[</span><span style="color:#6CB6FF">0</span><span style="color:#96D0FF">].</span><span style="color:#ADBAC7">id</span><span style="color:#96D0FF">}`</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#ADBAC7">  </span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">>User: </span><span style="color:#F47067">{</span><span style="color:#ADBAC7">user.name</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">, Posts: </span><span style="color:#F47067">{</span><span style="color:#ADBAC7">posts.</span><span style="color:#6CB6FF">length</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">, Comments: </span><span style="color:#F47067">{</span><span style="color:#ADBAC7">comments.</span><span style="color:#6CB6FF">length</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">>;</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>If each fetch takes 200ms, you're at 600ms. That adds up fast.</p>
<p><strong>The fix:</strong> Fetch in parallel.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="js" data-theme="github-dark-dimmed"><code data-language="js" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// ✅ Parallel fetches = fast</span></span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> default</span><span style="color:#F47067"> async</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> Page</span><span style="color:#F69D50">({ params }) </span><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#ADBAC7"> [</span><span style="color:#6CB6FF">user</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">posts</span><span style="color:#ADBAC7">] </span><span style="color:#F47067">=</span><span style="color:#F47067"> await</span><span style="color:#6CB6FF"> Promise</span><span style="color:#ADBAC7">.</span><span style="color:#DCBDFB">all</span><span style="color:#ADBAC7">([</span></span>
<span data-line=""><span style="color:#DCBDFB">    fetch</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">`/api/users/${</span><span style="color:#ADBAC7">params</span><span style="color:#96D0FF">.</span><span style="color:#ADBAC7">id</span><span style="color:#96D0FF">}`</span><span style="color:#ADBAC7">),</span></span>
<span data-line=""><span style="color:#DCBDFB">    fetch</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">`/api/posts?userId=${</span><span style="color:#ADBAC7">params</span><span style="color:#96D0FF">.</span><span style="color:#ADBAC7">id</span><span style="color:#96D0FF">}`</span><span style="color:#ADBAC7">),</span></span>
<span data-line=""><span style="color:#ADBAC7">  ]);</span></span>
<span data-line=""><span style="color:#ADBAC7">  </span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> comments</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#DCBDFB"> fetch</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">`/api/comments?postId=${</span><span style="color:#ADBAC7">posts</span><span style="color:#96D0FF">[</span><span style="color:#6CB6FF">0</span><span style="color:#96D0FF">].</span><span style="color:#ADBAC7">id</span><span style="color:#96D0FF">}`</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#ADBAC7">  </span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">>User: </span><span style="color:#F47067">{</span><span style="color:#ADBAC7">user.name</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">, Posts: </span><span style="color:#F47067">{</span><span style="color:#ADBAC7">posts.</span><span style="color:#6CB6FF">length</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">, Comments: </span><span style="color:#F47067">{</span><span style="color:#ADBAC7">comments.</span><span style="color:#6CB6FF">length</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">>;</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>Now user and posts fetch together. Comments depends on posts, so it waits. Total time: ~400ms instead of 600ms. That's real.</p>
<h2>Missing cache headers</h2>
<p>You deployed a static page (or it should be static). But your API doesn't set cache headers, so Next.js re-fetches from your origin on every request. Your CDN can't cache it.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="js" data-theme="github-dark-dimmed"><code data-language="js" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// ❌ No cache headers = re-fetching everything</span></span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> default</span><span style="color:#F47067"> async</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> Page</span><span style="color:#F69D50">() </span><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> data</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#DCBDFB"> fetch</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">`/api/products`</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">></span><span style="color:#F47067">{</span><span style="color:#768390">/* render products */</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">>;</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>Each visitor re-hits your database. Your server starts sweating.</p>
<p><strong>The fix:</strong> Add cache headers to your API, and tell Next.js to cache the fetch.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="js" data-theme="github-dark-dimmed"><code data-language="js" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// ✅ Cache headers + Next.js config</span></span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> default</span><span style="color:#F47067"> async</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> Page</span><span style="color:#F69D50">() </span><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> data</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#DCBDFB"> fetch</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">`/api/products`</span><span style="color:#ADBAC7">, {</span></span>
<span data-line=""><span style="color:#ADBAC7">    next: { revalidate: </span><span style="color:#6CB6FF">3600</span><span style="color:#ADBAC7"> }, </span><span style="color:#768390">// cache for 1 hour</span></span>
<span data-line=""><span style="color:#ADBAC7">  });</span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">></span><span style="color:#F47067">{</span><span style="color:#768390">/* render products */</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">>;</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>And on your API route:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="js" data-theme="github-dark-dimmed"><code data-language="js" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> async</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> GET</span><span style="color:#ADBAC7">() {</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> products</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#ADBAC7"> db.</span><span style="color:#DCBDFB">getProducts</span><span style="color:#ADBAC7">();</span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> Response.</span><span style="color:#DCBDFB">json</span><span style="color:#ADBAC7">(products, {</span></span>
<span data-line=""><span style="color:#ADBAC7">    headers: {</span></span>
<span data-line=""><span style="color:#96D0FF">      'Cache-Control'</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">'public, max-age=3600, s-maxage=3600'</span><span style="color:#ADBAC7">,</span></span>
<span data-line=""><span style="color:#ADBAC7">    },</span></span>
<span data-line=""><span style="color:#ADBAC7">  });</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>Now your CDN caches it. Your origin takes 1/100th the requests. Your database can breathe.</p>
<h2>Generating static pages when you can</h2>
<p>Not every page needs to be dynamic. If your product listing doesn't change every minute, generate it at build time (or at request time and cache it).</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="js" data-theme="github-dark-dimmed"><code data-language="js" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// ❌ Dynamic rendering on every request (even if data doesn't change)</span></span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> default</span><span style="color:#F47067"> async</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> Page</span><span style="color:#F69D50">() </span><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> products</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#DCBDFB"> fetch</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">`/api/products`</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">></span><span style="color:#F47067">{</span><span style="color:#768390">/* render */</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">>;</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p><strong>The fix:</strong> Use <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>generateStaticParams</span></span></code></span> for predictable routes and ISR for the rest.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="js" data-theme="github-dark-dimmed"><code data-language="js" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// ✅ Static generation + revalidation</span></span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> const</span><span style="color:#6CB6FF"> revalidate</span><span style="color:#F47067"> =</span><span style="color:#6CB6FF"> 3600</span><span style="color:#ADBAC7">; </span><span style="color:#768390">// revalidate every hour</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> async</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> generateStaticParams</span><span style="color:#ADBAC7">() {</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> categories</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#ADBAC7"> db.</span><span style="color:#DCBDFB">getCategories</span><span style="color:#ADBAC7">();</span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> categories.</span><span style="color:#DCBDFB">map</span><span style="color:#ADBAC7">((</span><span style="color:#F69D50">cat</span><span style="color:#ADBAC7">) </span><span style="color:#F47067">=></span><span style="color:#ADBAC7"> ({ category: cat.slug }));</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> default</span><span style="color:#F47067"> async</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> Page</span><span style="color:#F69D50">({ params }) </span><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> products</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#DCBDFB"> fetch</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">`/api/products?category=${</span><span style="color:#ADBAC7">params</span><span style="color:#96D0FF">.</span><span style="color:#ADBAC7">category</span><span style="color:#96D0FF">}`</span><span style="color:#ADBAC7">, {</span></span>
<span data-line=""><span style="color:#ADBAC7">    next: { revalidate: </span><span style="color:#6CB6FF">3600</span><span style="color:#ADBAC7"> },</span></span>
<span data-line=""><span style="color:#ADBAC7">  });</span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">></span><span style="color:#F47067">{</span><span style="color:#768390">/* render */</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">>;</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>Now Next.js generates those pages once (or every hour). Visitors get static HTML. Instant.</p>
<h2>Profile before you optimize</h2>
<p>I spent an hour optimizing the wrong thing last week. Check where the time actually goes:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="bash" data-theme="github-dark-dimmed"><code data-language="bash" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390"># Use Next.js build output to see which routes are slow</span></span>
<span data-line=""><span style="color:#F69D50">npm</span><span style="color:#96D0FF"> run</span><span style="color:#96D0FF"> build</span></span></code></pre></figure>
<p>Look at the build output. See <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>Static</span></span></code></span> vs <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>Dynamic</span></span></code></span> vs <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>ISR</span></span></code></span>. If something's dynamic that shouldn't be, fix it.</p>
<p>Use DevTools Network tab in production (or your analytics). Where are users waiting?</p>
<h2>The real wins</h2>
<ul>
<li><strong>Kill waterfalls:</strong> <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>Promise.all()</span></span></code></span> for parallel fetches.</li>
<li><strong>Cache headers:</strong> Set them on your API. Let CDNs and Next.js cache.</li>
<li><strong>Static where possible:</strong> If data doesn't change every request, don't fetch every request.</li>
<li><strong>Measure:</strong> Profile before you panic.</li>
</ul>
<p>I saved 300ms on one page just by parallelizing three fetches. Another 200ms by adding cache headers. That's half a second that users <em>feel</em>.</p>
<p>Next.js is already fast. These patterns just stop you from accidentally making it slow.</p>
<p>— Mustaque</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Component Composition: why 'slot' patterns beat prop drilling every time]]></title>
            <link>https://mustaquenadim.com/blog/component-composition-patterns</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/component-composition-patterns</guid>
            <pubDate>Thu, 26 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[How flexible composition and render props save you from prop drilling hell and make components genuinely reusable.]]></description>
            <content:encoded><![CDATA[<p>I spent way too long drilling props three levels deep before I learned that composition fixes most of these problems instantly. Once you see it, you can't unsee it.</p>
<h2>The prop drilling trap</h2>
<p>You start with a button. Then a modal wraps the button. Then a form wraps the modal. Then the page wraps everything. By the time you're styling that button, you're threading <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>size</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>variant</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>disabled</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>onClick</span></span></code></span> through six layers of components. Each layer adds indirection. Each indirection is a place where bugs hide.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// ❌ This scales poorly</span></span>
<span data-line=""><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">Page</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  &#x3C;</span><span style="color:#8DDB8C">Form</span><span style="color:#6CB6FF"> buttonSize</span><span style="color:#F47067">=</span><span style="color:#96D0FF">"lg"</span><span style="color:#6CB6FF"> buttonVariant</span><span style="color:#F47067">=</span><span style="color:#96D0FF">"primary"</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;</span><span style="color:#8DDB8C">Modal</span><span style="color:#6CB6FF"> title</span><span style="color:#F47067">=</span><span style="color:#96D0FF">"Confirm"</span><span style="color:#6CB6FF"> actionButtonLabel</span><span style="color:#F47067">=</span><span style="color:#96D0FF">"Save"</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">Button</span><span style="color:#6CB6FF"> size</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">buttonSize</span><span style="color:#F47067">}</span><span style="color:#6CB6FF"> variant</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">buttonVariant</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> /></span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;/</span><span style="color:#8DDB8C">Modal</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  &#x3C;/</span><span style="color:#8DDB8C">Form</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">Page</span><span style="color:#ADBAC7">></span></span></code></pre></figure>
<h2>Composition via children and slots</h2>
<p>The fix is simple: stop passing data through the tree. Instead, pass the component itself.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// ✅ Compose directly</span></span>
<span data-line=""><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">Page</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  &#x3C;</span><span style="color:#8DDB8C">Form</span></span>
<span data-line=""><span style="color:#6CB6FF">    actions</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">Button</span><span style="color:#6CB6FF"> size</span><span style="color:#F47067">=</span><span style="color:#96D0FF">"lg"</span><span style="color:#6CB6FF"> variant</span><span style="color:#F47067">=</span><span style="color:#96D0FF">"primary"</span><span style="color:#ADBAC7">>Save&#x3C;/</span><span style="color:#8DDB8C">Button</span><span style="color:#ADBAC7">></span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#ADBAC7">  ></span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;</span><span style="color:#8DDB8C">Modal</span><span style="color:#6CB6FF"> title</span><span style="color:#F47067">=</span><span style="color:#96D0FF">"Confirm"</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#F47067">      {</span><span style="color:#768390">/* Button is already baked in, no props needed */</span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;/</span><span style="color:#8DDB8C">Modal</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  &#x3C;/</span><span style="color:#8DDB8C">Form</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">Page</span><span style="color:#ADBAC7">></span></span></code></pre></figure>
<p>Now the button is defined once, at the call site. Modal doesn't care about button props. Form doesn't care either. Each component only knows its own business.</p>
<h2>Render props for dynamic control</h2>
<p>Sometimes you need the child to control what renders. That's where render props shine:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">DataTable</span></span>
<span data-line=""><span style="color:#6CB6FF">  data</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">items</span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#6CB6FF">  renderRow</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">item</span><span style="color:#ADBAC7">) </span><span style="color:#F47067">=></span><span style="color:#ADBAC7"> (</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;</span><span style="color:#8DDB8C">tr</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">td</span><span style="color:#ADBAC7">></span><span style="color:#F47067">{</span><span style="color:#ADBAC7">item.name</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">td</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">td</span><span style="color:#ADBAC7">></span><span style="color:#F47067">{</span><span style="color:#ADBAC7">item.value</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">td</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;/</span><span style="color:#8DDB8C">tr</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  )</span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#ADBAC7">/></span></span></code></pre></figure>
<p>The table owns the iteration and row context. The caller owns the presentation. No prop drilling. The logic stays clean.</p>
<h2>Real-world wins</h2>
<p>I used this pattern recently on a filterable list component. Instead of passing <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>onFilter</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>filterPlaceholder</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>filterDebounce</span></span></code></span>, etc., I just accepted:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">FilterableList</span></span>
<span data-line=""><span style="color:#6CB6FF">  data</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">items</span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#6CB6FF">  renderFilter</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">value</span><span style="color:#ADBAC7">, </span><span style="color:#F69D50">onChange</span><span style="color:#ADBAC7">) </span><span style="color:#F47067">=></span><span style="color:#ADBAC7"> (</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;</span><span style="color:#8DDB8C">input</span><span style="color:#6CB6FF"> value</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">value</span><span style="color:#F47067">}</span><span style="color:#6CB6FF"> onChange</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">onChange</span><span style="color:#F47067">}</span><span style="color:#6CB6FF"> placeholder</span><span style="color:#F47067">=</span><span style="color:#96D0FF">"Search..."</span><span style="color:#ADBAC7"> /></span></span>
<span data-line=""><span style="color:#ADBAC7">  )</span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#6CB6FF">  renderItem</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">item</span><span style="color:#ADBAC7">) </span><span style="color:#F47067">=></span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">ItemCard</span><span style="color:#F47067"> {...</span><span style="color:#ADBAC7">item</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> /></span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#ADBAC7">/></span></span></code></pre></figure>
<p>The component owns filtering logic. The caller owns UI. Zero prop drilling. Dead simple to test each piece independently.</p>
<h2>When context still wins</h2>
<p>For truly global state (theme, locale, user), context is still the right choice. But for local component communication? Composition beats context every time because it's explicit, debuggable, and doesn't hide dependencies.</p>
<h2>Key takeaway</h2>
<p>Prop drilling feels like it'll just be two more props. Then it's five. Then it's seventeen and you're wondering why a button component needs to know about form state.</p>
<p>Composition (slots, render props, or children) is not fancier — it's clearer. The data flows where it's visible. The component boundaries stay clean. Your future self will be grateful.</p>
<p>— Mustaque</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Keeping state predictable in React: small habits that save hours]]></title>
            <link>https://mustaquenadim.com/blog/keeping-state-in-react</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/keeping-state-in-react</guid>
            <pubDate>Wed, 25 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Practical tips for managing React state with clarity, scale, and less friction — focused on patterns I use daily.]]></description>
            <content:encoded><![CDATA[<p>I used to treat state like a second-class citizen: push it around, patch it in a hurry, and then wonder why bugs popped up days later. Over time I learned a few small habits that make state predictable and debugging less painful. These are the things I actually still do on real projects.</p>
<ol>
<li>Prefer explicit state shape over ad-hoc objects</li>
</ol>
<p>Pick a clear shape and stick to it. If a component needs {loading, error, data}, keep that consistent across similar components. When shape is predictable, you can reason about transitions rather than individual fields.</p>
<ol start="2">
<li>Co-locate the minimal state</li>
</ol>
<p>Keep state as close as possible to where it's used. Derived values belong in selectors or computed values, not in the shared writable state. Move state up only when multiple children truly need it.</p>
<ol start="3">
<li>Favor immutable updates (even in small apps)</li>
</ol>
<p>Using shallow copies with spread or helper utilities prevents accidental mutations that leak through props. The mental overhead is small; the benefits compound when you revisit code later.</p>
<ol start="4">
<li>Use local reducers for complex local logic</li>
</ol>
<p>If a single component has several interacting flags, a small useReducer keeps transitions explicit and testable compared to juggling multiple useState calls.</p>
<ol start="5">
<li>Keep side effects predictable</li>
</ol>
<p>Prefer effects that are idempotent and derive from state changes. Isolate subscriptions and clean them up. When side effects are tangled with rendering, it's much harder to reason about the state machine.</p>
<ol start="6">
<li>Prefer explicit events rather than implicit mutations</li>
</ol>
<p>Name the intent (e.g., 'startFetch', 'fetchSuccess', 'fetchFailure') instead of hiding behavior inside setters. Event names read better in logs and tests.</p>
<ol start="7">
<li>Add cheap tests for reducers and selectors</li>
</ol>
<p>They don't need to be exhaustive — test the important happy and unhappy paths. Tests are the fastest way to catch regressions as your app grows.</p>
<p>Closing thought</p>
<p>Small, consistent habits add up. If you make state predictable, your future self will thank you when an afternoon of debugging becomes a 10‑minute fix. The real win is not a specific library or framework — it's a pattern of thinking about state transitions clearly.</p>
<p>— Mustaque</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[React Server Components: Separating Hype from Reality]]></title>
            <link>https://mustaquenadim.com/blog/react-server-components-misconceptions</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/react-server-components-misconceptions</guid>
            <pubDate>Mon, 23 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Breaking down the misconceptions around RSCs and why they're actually a brilliant rethink of the client-server split.]]></description>
            <content:encoded><![CDATA[<p>When React Server Components first arrived, I was skeptical. "Is this just going backwards?" I thought. "Aren't we supposed to have the freedom of client-side rendering?"</p>
<p>Six months into working with them, I've realized how much I had it backwards.</p>
<h2>The Core Misconception</h2>
<p>Most of us grew up thinking: <strong>JavaScript frameworks live on the client. That's the whole point.</strong></p>
<p>React Server Components flip this (slightly) by saying: <strong>Some things don't need to be JavaScript at all.</strong> And that's actually profound.</p>
<p>The misconception I see most often: "RSCs mean we're ditching client-side React."</p>
<p>Reality: RSCs let you use React syntax server-side to produce <em>less JavaScript</em> sent to the client. Your interactive components still run client-side. You just get to choose what needs to be interactive.</p>
<h2>Why This Actually Matters</h2>
<p>Think about a typical dashboard. You have:</p>
<ul>
<li>A data table (doesn't need to be interactive)</li>
<li>A filter sidebar (absolutely needs interactivity)</li>
<li>A header with real-time notifications (needs interactivity)</li>
</ul>
<p>Pre-RSCs, we'd either:</p>
<ol>
<li>Send the entire thing as client JS and pay the bundle cost</li>
<li>Render it server-side and lose the ability to use your component framework</li>
</ol>
<p>With RSCs, you render the table server-side (no JS needed), make the sidebar and header Client Components, and everyone wins. The client gets less JavaScript. Your components stay composable. Your data fetching is straightforward.</p>
<h2>The "Feels Weird" Part</h2>
<p>Yeah, async components feel strange at first:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F47067">async</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> PostList</span><span style="color:#ADBAC7">() {</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> posts</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#DCBDFB"> fetch</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">'https://api.example.com/posts'</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> (</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;</span><span style="color:#8DDB8C">ul</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#F47067">      {</span><span style="color:#ADBAC7">posts.</span><span style="color:#DCBDFB">map</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">post</span><span style="color:#F47067"> =></span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">li</span><span style="color:#6CB6FF"> key</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">post.id</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">></span><span style="color:#F47067">{</span><span style="color:#ADBAC7">post.title</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">li</span><span style="color:#ADBAC7">>)</span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;/</span><span style="color:#8DDB8C">ul</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  );</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>But think about it: this is just... normal server code. It's familiar. No more useState hooks for loading states that could've just been fetched upfront. No useEffect dancing around data fetching.</p>
<p>The mind-shift: <strong>You're not writing "server code" and "client code" anymore. You're writing React. The framework figures out where it runs.</strong></p>
<h2>The Real Gotcha</h2>
<p>The part nobody talks about: state management becomes more interesting.</p>
<p>If your Server Component fetches data and passes it as a prop to a Client Component that modifies it... you need a way to refetch or update that data. That's where mutations (server actions) come in. And yeah, that takes getting used to.</p>
<p>But once you do? You realize you've eliminated an entire class of bugs. No more "stale data on the client" problems. Your server is still the source of truth. You're just being smarter about what computation lives where.</p>
<h2>The Honest Take</h2>
<p>RSCs aren't a silver bullet. You don't need them for every app. A highly interactive dashboard with tons of real-time updates? Maybe stick with a traditional client-heavy approach.</p>
<p>But for content-rich applications, product pages, dashboards with mostly-static sections? RSCs are a genuine quality-of-life improvement. Smaller bundles. Simpler component logic. Less JavaScript to ship.</p>
<p>And honestly, that's pretty cool.</p>
<p>The future probably isn't "everything server" or "everything client." It's thoughtful about what goes where. RSCs are just giving you better tools to be thoughtful about it.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[From Hydration Drag to Fast Pages: My Small Wins with Server Components]]></title>
            <link>https://mustaquenadim.com/blog/server-components-small-wins</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/server-components-small-wins</guid>
            <pubDate>Mon, 23 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Practical tips I learned when moving parts of my Next.js UI to server components to cut hydration cost]]></description>
            <content:encoded><![CDATA[<p>I used to measure page speed the wrong way: open DevTools, click refresh, curse at a long "hydration" period, and then reach for bigger bundles or complex caching. After a few painful deploys and a clearer look at where time was going, I realized the real win wasn't magic tooling — it was moving as much as possible off the client and being deliberate about the little interactive islands that remained.</p>
<p>Here are the practical rules I ended up following and how they helped.</p>
<h2>1) Start with the expensive parts</h2>
<p>If a component doesn't need event handlers, timers, or browser-only APIs, render it on the server. That immediately removes its hydration cost.</p>
<p>Example: a blog post where the header, markdown renderer, and related links can be server-rendered, while the comment box remains interactive.</p>
<h2>2) Keep client islands tiny</h2>
<p>Instead of wrapping a whole page in a client bundle, isolate the bits that actually need JS. Smaller islands = less JS to hydrate.</p>
<p>Client component example:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// components/LikeButton.client.jsx</span></span>
<span data-line=""><span style="color:#96D0FF">'use client'</span></span>
<span data-line=""><span style="color:#F47067">import</span><span style="color:#ADBAC7"> { useState } </span><span style="color:#F47067">from</span><span style="color:#96D0FF"> 'react'</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> default</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> LikeButton</span><span style="color:#F69D50">({ initial }) </span><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#ADBAC7"> [</span><span style="color:#6CB6FF">count</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">setCount</span><span style="color:#ADBAC7">] </span><span style="color:#F47067">=</span><span style="color:#DCBDFB"> useState</span><span style="color:#ADBAC7">(initial)</span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> (</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;</span><span style="color:#8DDB8C">button</span><span style="color:#6CB6FF"> onClick</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">() </span><span style="color:#F47067">=></span><span style="color:#DCBDFB"> setCount</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">c</span><span style="color:#F47067"> =></span><span style="color:#ADBAC7"> c </span><span style="color:#F47067">+</span><span style="color:#6CB6FF"> 1</span><span style="color:#ADBAC7">)</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">      ❤️ </span><span style="color:#F47067">{</span><span style="color:#ADBAC7">count</span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;/</span><span style="color:#8DDB8C">button</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  )</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>Then import it into a server component:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// app/post/[slug].jsx (server component)</span></span>
<span data-line=""><span style="color:#F47067">import</span><span style="color:#ADBAC7"> LikeButton </span><span style="color:#F47067">from</span><span style="color:#96D0FF"> '../../components/LikeButton.client'</span></span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> default</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> Post</span><span style="color:#F69D50">({ params }) </span><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> post</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#DCBDFB"> getPost</span><span style="color:#ADBAC7">(params.slug) </span><span style="color:#768390">// server-side fetch</span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> (</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;></span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">h1</span><span style="color:#ADBAC7">></span><span style="color:#F47067">{</span><span style="color:#ADBAC7">post.title</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">h1</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">article</span><span style="color:#6CB6FF"> dangerouslySetInnerHTML</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">{ __html: post.html }</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> /></span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">LikeButton</span><span style="color:#6CB6FF"> initial</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">post.likes</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> /></span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;/></span></span>
<span data-line=""><span style="color:#ADBAC7">  )</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>Note: the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>.client</span></span></code></span> suffix (or <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>use client</span></span></code></span>) makes intent explicit. The rest of the page stays server-rendered.</p>
<h2>3) Prefer server data fetching for static content</h2>
<p>When content doesn't need to be live, fetch it on the server and cache aggressively. This reduced my bundle size and eliminated duplicated fetching logic across client components.</p>
<h2>4) Be pragmatic with interactivity</h2>
<p>I used optimistic UI for small actions (likes, toggles) and delegated heavy state or subscriptions to dedicated client modules. If a feature becomes large and interactive (e.g., a real-time chat), make it a focused client app within the page, not a blanket client conversion.</p>
<h2>5) Measure the right things</h2>
<p>Look at "Time to Interactive" and "Total Blocking Time" and — crucially — the hydration waterfall in the Performance tab. After moving most UI to the server, my hydration times dropped and TTI improved without touching third-party scripts.</p>
<blockquote>
<p>Small, focused changes compound. Moving one big table or list to render on the server often gives more improvement than trimming random imports.</p>
</blockquote>
<p>If you're migrating an existing app, don't try to convert everything at once. Start with the parts that add the most JavaScript and move outward. The payoff is less cognitive overhead for your users and fewer build-time surprises for you.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Why Developers Secretly Hate Agile (And How to Actually Make It Work)]]></title>
            <link>https://mustaquenadim.com/blog/why-developers-hate-agile</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/why-developers-hate-agile</guid>
            <pubDate>Sun, 22 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Agile was supposed to be the holy grail of software development, but for many teams, it's just micromanagement in disguise. Here's a raw take on where it goes wrong and how to fix it.]]></description>
            <content:encoded><![CDATA[<p>Let’s be brutally honest for a second: most developers don't actually like Agile.</p>
<p>We tolerate it. We sit through the endless sprint planning meetings, we move our little Jira tickets from "In Progress" to "Code Review," and we nod along during daily standups while secretly writing a script in our heads to automate the update we're about to give.</p>
<p>But Agile, as it was originally conceived, is practically dead. What most teams are doing today isn't Agile; it's just micromanagement dressed up in a trendy suit.</p>
<p>Here is why it happens, and more importantly, how I've seen teams successfully flip the script.</p>
<h3>The Illusion of Velocity</h3>
<p>The biggest problem with modern Agile is the obsession with "velocity." Management loves a good burndown chart. It gives the illusion of control and predictability in a field that is inherently chaotic and unpredictable.</p>
<p>So, what happens? Teams start optimizing for velocity instead of value. We break down tasks into microscopic, easily digestible chunks just so we can show progress every single day. We stop taking risks, we stop tackling complex, ambiguous problems, and we start churning out features that nobody asked for just to hit our sprint commitments.</p>
<p>It’s exhausting, and frankly, it kills creativity.</p>
<h3>The Death of Deep Work</h3>
<p>Agile, especially Scrum, is an interruption engine.</p>
<p>Between daily standups, backlog grooming, sprint planning, and retrospectives, it feels like half the week is spent talking about the work rather than actually doing the work.</p>
<p>As a developer (especially when I'm deep into a complex React architecture or trying to debug a weird Next.js routing issue), I need long, uninterrupted blocks of time. I need to hold the entire system in my head. When you interrupt me for a 15-minute standup, you aren't just taking 15 minutes of my time; you're taking the 30 minutes it takes me to get back into the flow state.</p>
<h3>How to Actually Make It Work</h3>
<p>I don't hate the core principles of Agile. The idea of iterating quickly, responding to change, and collaborating closely with stakeholders is fantastic. It's the rigid implementation that ruins it.</p>
<p>Here are three things that have actually made a difference in the teams I've worked with:</p>
<h4>1. Async Standups Are a Superpower</h4>
<p>Unless there is a literal fire in production, there is zero reason for a daily synchronous standup. Move it to Slack or Discord.</p>
<p>Have everyone post a quick update by 10 AM:</p>
<ul>
<li>What I did yesterday.</li>
<li>What I'm doing today.</li>
<li>What's blocking me.</li>
</ul>
<p>If someone is blocked, they can jump on a quick huddle with the person who can unblock them. It saves time, it respects people's flow states, and it creates a searchable history of what the team is working on.</p>
<h4>2. Stop Pointing Every Single Ticket</h4>
<p>Estimating is a trap. We all know that story points are made up, yet we treat them like binding contracts.</p>
<p>Instead of spending an hour agonizing over whether a ticket is a 3, a 5, or an 8, just focus on breaking the work down into reasonable chunks that can be completed in a few days. If a task takes longer, communicate it. The goal is to deliver working software, not to accurately predict the future.</p>
<h4>3. Protect "Maker Time" at All Costs</h4>
<p>This is the most important one. Teams need dedicated, meeting-free days.</p>
<p>In a previous role, we implemented "No Meeting Thursdays." It was a game-changer. The amount of deep, focused work that got done on Thursdays consistently outpaced the rest of the week combined.</p>
<p>If you manage a team, your primary job is to protect your developers' time. Shield them from the noise. Let them build.</p>
<h3>The Takeaway</h3>
<p>Agile isn't inherently evil, but the way we've bastardized it into a rigid, metric-obsessed methodology is slowly killing the joy of building software.</p>
<p>If we want to build better products, we need to stop optimizing for burndown charts and start optimizing for developer happiness and flow state.</p>
<p>What has your experience been with Agile? Has it helped or hindered your productivity? Let me know!</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[React Suspense Demystified: It's Just a Fancy Try/Catch]]></title>
            <link>https://mustaquenadim.com/blog/react-suspense-simplified</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/react-suspense-simplified</guid>
            <pubDate>Sat, 21 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Understanding React Suspense doesn't have to be complicated. Let's break down how it actually works under the hood and why it changed the way we build UIs.]]></description>
            <content:encoded><![CDATA[<p>I used to be terrified of React Suspense. When it first dropped, I read the docs and my eyes completely glazed over. "Algebraic effects?" "Throwing promises?" It sounded like some academic computer science concept that I was definitely not smart enough to understand.</p>
<p>But after spending way too much time debugging loading states in a complex Next.js app last week, I finally had one of those "aha!" moments. And honestly? It's much simpler than we make it out to be.</p>
<p>Let's talk about what Suspense actually is, minus the jargon.</p>
<h2>The Old Way: State Soup</h2>
<p>Remember how we used to handle loading data? If you've written React for more than a month, you've written this component:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F47067">function</span><span style="color:#DCBDFB"> UserProfile</span><span style="color:#ADBAC7">({ </span><span style="color:#F69D50">id</span><span style="color:#ADBAC7"> }) {</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#ADBAC7"> [</span><span style="color:#6CB6FF">data</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">setData</span><span style="color:#ADBAC7">] </span><span style="color:#F47067">=</span><span style="color:#DCBDFB"> useState</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">null</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#ADBAC7"> [</span><span style="color:#6CB6FF">loading</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">setLoading</span><span style="color:#ADBAC7">] </span><span style="color:#F47067">=</span><span style="color:#DCBDFB"> useState</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">true</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#ADBAC7"> [</span><span style="color:#6CB6FF">error</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">setError</span><span style="color:#ADBAC7">] </span><span style="color:#F47067">=</span><span style="color:#DCBDFB"> useState</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">null</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#DCBDFB">  useEffect</span><span style="color:#ADBAC7">(() </span><span style="color:#F47067">=></span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#DCBDFB">    fetchUser</span><span style="color:#ADBAC7">(id)</span></span>
<span data-line=""><span style="color:#ADBAC7">      .</span><span style="color:#DCBDFB">then</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">res</span><span style="color:#F47067"> =></span><span style="color:#DCBDFB"> setData</span><span style="color:#ADBAC7">(res))</span></span>
<span data-line=""><span style="color:#ADBAC7">      .</span><span style="color:#DCBDFB">catch</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">err</span><span style="color:#F47067"> =></span><span style="color:#DCBDFB"> setError</span><span style="color:#ADBAC7">(err))</span></span>
<span data-line=""><span style="color:#ADBAC7">      .</span><span style="color:#DCBDFB">finally</span><span style="color:#ADBAC7">(() </span><span style="color:#F47067">=></span><span style="color:#DCBDFB"> setLoading</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">false</span><span style="color:#ADBAC7">));</span></span>
<span data-line=""><span style="color:#ADBAC7">  }, [id]);</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">  if</span><span style="color:#ADBAC7"> (loading) </span><span style="color:#F47067">return</span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">Spinner</span><span style="color:#ADBAC7"> />;</span></span>
<span data-line=""><span style="color:#F47067">  if</span><span style="color:#ADBAC7"> (error) </span><span style="color:#F47067">return</span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">ErrorMessage</span><span style="color:#6CB6FF"> error</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">error</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> />;</span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">ProfileCard</span><span style="color:#6CB6FF"> user</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">data</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> />;</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>It works, but it scales terribly. If <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>ProfileCard</span></span></code></span> has children that also need to fetch data, you end up with "waterfalls" (fetching data sequentially) and spinner-ception (spinners rendering inside spinners rendering inside spinners).</p>
<h2>The Mental Shift</h2>
<p>Here is the secret to understanding Suspense: <strong>React Suspense is just <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>try/catch</span></span></code></span> for loading states.</strong></p>
<p>When you write a normal JavaScript function, and something goes wrong, you can <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>throw</span></span></code></span> an error. The engine stops executing that function and looks up the call stack for the nearest <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>catch</span></span></code></span> block to handle it.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="javascript" data-theme="github-dark-dimmed"><code data-language="javascript" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F47067">try</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#768390">  // If something in here throws an error...</span></span>
<span data-line=""><span style="color:#DCBDFB">  doRiskyThing</span><span style="color:#ADBAC7">(); </span></span>
<span data-line=""><span style="color:#ADBAC7">} </span><span style="color:#F47067">catch</span><span style="color:#ADBAC7"> (error) {</span></span>
<span data-line=""><span style="color:#768390">  // ...it gets caught and handled here.</span></span>
<span data-line=""><span style="color:#ADBAC7">  console.</span><span style="color:#DCBDFB">log</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">"Caught it!"</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>Suspense works exactly the same way, but instead of throwing <em>errors</em>, your components throw <em>Promises</em> (the data they are waiting for).</p>
<h2>How Suspense Actually Works</h2>
<p>When a component is rendering, if it realizes it needs data it doesn't have yet, it literally <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>throw</span></span></code></span>s a Promise to React.</p>
<p>React catches that Promise. It stops rendering the component, says "Okay, I'll wait for this Promise to resolve," and looks up the tree for the nearest <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>&#x3C;Suspense></span></span></code></span> boundary. It then renders the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>fallback</span></span></code></span> UI from that boundary.</p>
<p>Once the Promise resolves (the data is ready), React re-renders the component. This time, the data is there, so the component doesn't throw, and it renders normally.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// The boundary (the "catch" block)</span></span>
<span data-line=""><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">Suspense</span><span style="color:#6CB6FF"> fallback</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">SkeletonProfile</span><span style="color:#ADBAC7"> /></span><span style="color:#F47067">}</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#F47067">  {</span><span style="color:#768390">/* The component that might "throw" a Promise */</span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#ADBAC7">  &#x3C;</span><span style="color:#8DDB8C">UserProfile</span><span style="color:#6CB6FF"> id</span><span style="color:#F47067">={</span><span style="color:#6CB6FF">123</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> /></span></span>
<span data-line=""><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">Suspense</span><span style="color:#ADBAC7">></span></span></code></pre></figure>
<p>That's it. That's the whole magic trick.</p>
<p>By pulling the loading state <em>out</em> of the component and putting it into the parent boundary, we stop polluting our UI components with <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>isLoading</span></span></code></span> checks. Our components get to pretend the data is always there.</p>
<h2>Why This Matters</h2>
<p>This isn't just a syntactic sugar. It fundamentally changes how we compose UIs:</p>
<ol>
<li><strong>Better DX:</strong> You write components as if they are synchronous. No more <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>if (loading)</span></span></code></span> boilerplate.</li>
<li><strong>Orchestration:</strong> You can wrap multiple fetching components in a <em>single</em> Suspense boundary. They will fetch in parallel, and the boundary will wait for <em>all</em> of them before hiding the spinner.</li>
<li><strong>Streaming:</strong> If you use React Server Components (which you probably are if you're on modern Next.js), Suspense tells the server exactly where to split the HTML stream. It streams the fallback immediately, then streams the real content when it's ready.</li>
</ol>
<p>Next time you see <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>&#x3C;Suspense></span></span></code></span>, don't overthink it. Just read it as: "Try to render the stuff inside here. If any of it isn't ready yet, show this fallback until it is."</p>
<p>Happy coding!</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[The React Server Components Mental Model I Wish I Had Sooner]]></title>
            <link>https://mustaquenadim.com/blog/react-server-components-mental-model</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/react-server-components-mental-model</guid>
            <pubDate>Thu, 19 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[RSCs are confusing until you stop thinking about them as just another React component.]]></description>
            <content:encoded><![CDATA[<p>For a long time, React Server Components (RSCs) felt like magic to me. Magic is cool when you're watching a show, but terrible when you're trying to debug a production app.</p>
<p>Every time I tried to use them, I'd end up with a dreaded <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>Error: Cannot use useState in a Server Component</span></span></code></span>. Sound familiar?</p>
<p>The problem wasn't the technology. The problem was my mental model. I was still thinking about them as "React components that happen to run on the server."</p>
<p>They aren't.</p>
<h3>The Mental Shift</h3>
<p>Here's the analogy that finally made it click for me:</p>
<p><strong>Think of Server Components as your backend API, and Client Components as your frontend app.</strong></p>
<p>Imagine you're building a traditional app. You write a Node.js endpoint that talks to a database, formats the data, and sends JSON to the client. The client receives that JSON, puts it in state, and renders it.</p>
<p>With RSCs, you're doing the exact same thing, but instead of sending JSON over the wire, you're sending <em>UI</em>.</p>
<p>Server Components:</p>
<ul>
<li>Run exactly once per request.</li>
<li>Have direct access to your database or filesystem.</li>
<li>CANNOT have state (<span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useState</span></span></code></span>), effects (<span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useEffect</span></span></code></span>), or interactivity (onClick). Why? Because they run on the server, not in the browser! There's no user to interact with them yet.</li>
</ul>
<p>Client Components:</p>
<ul>
<li>Run in the browser (and are pre-rendered on the server).</li>
<li>Have state, effects, and interactivity.</li>
<li>Cannot securely access your database directly.</li>
</ul>
<h3>The Boundary</h3>
<p>The most important concept to grasp is the boundary between the two.</p>
<p>When you add <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>"use client"</span></span></code></span> to the top of a file, you're drawing a line in the sand. You're saying, "Everything below this line needs to be shipped to the browser."</p>
<p>The beauty of the Next.js App Router is that it defaults to Server Components. You start on the server, fetching data right where it lives, and only cross that <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>"use client"</span></span></code></span> boundary when you absolutely need interactivity.</p>
<h3>An Example</h3>
<p>Let's look at a typical product page.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="tsx" data-theme="github-dark-dimmed"><code data-language="tsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// app/products/[id]/page.tsx (Server Component)</span></span>
<span data-line=""><span style="color:#F47067">import</span><span style="color:#ADBAC7"> { getProduct } </span><span style="color:#F47067">from</span><span style="color:#96D0FF"> '@/lib/db'</span></span>
<span data-line=""><span style="color:#F47067">import</span><span style="color:#ADBAC7"> AddToCartButton </span><span style="color:#F47067">from</span><span style="color:#96D0FF"> './AddToCartButton'</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> default</span><span style="color:#F47067"> async</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> ProductPage</span><span style="color:#F69D50">({ params }) </span><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#768390">  // We're on the server. We can talk to the DB directly!</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> product</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#DCBDFB"> getProduct</span><span style="color:#ADBAC7">(params.id)</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> (</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">h1</span><span style="color:#ADBAC7">></span><span style="color:#F47067">{</span><span style="color:#ADBAC7">product.name</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">h1</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">p</span><span style="color:#ADBAC7">></span><span style="color:#F47067">{</span><span style="color:#ADBAC7">product.description</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">p</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">      </span></span>
<span data-line=""><span style="color:#F47067">      {</span><span style="color:#768390">/* We pass the data to a Client Component for interactivity */</span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">AddToCartButton</span><span style="color:#6CB6FF"> productId</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">product.id</span><span style="color:#F47067">}</span><span style="color:#6CB6FF"> price</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">product.price</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> /></span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;/</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  )</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>And the client component:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="tsx" data-theme="github-dark-dimmed"><code data-language="tsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// app/products/[id]/AddToCartButton.tsx</span></span>
<span data-line=""><span style="color:#96D0FF">"use client"</span><span style="color:#768390"> // &#x3C;-- The boundary</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">import</span><span style="color:#ADBAC7"> { useState } </span><span style="color:#F47067">from</span><span style="color:#96D0FF"> 'react'</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> default</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> AddToCartButton</span><span style="color:#F69D50">({ productId, price }) </span><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#ADBAC7"> [</span><span style="color:#6CB6FF">isAdding</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">setIsAdding</span><span style="color:#ADBAC7">] </span><span style="color:#F47067">=</span><span style="color:#DCBDFB"> useState</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">false</span><span style="color:#ADBAC7">)</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#DCBDFB"> handleAdd</span><span style="color:#F47067"> =</span><span style="color:#F47067"> async</span><span style="color:#ADBAC7"> () </span><span style="color:#F47067">=></span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#DCBDFB">    setIsAdding</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">true</span><span style="color:#ADBAC7">)</span></span>
<span data-line=""><span style="color:#768390">    // call api...</span></span>
<span data-line=""><span style="color:#DCBDFB">    setIsAdding</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">false</span><span style="color:#ADBAC7">)</span></span>
<span data-line=""><span style="color:#ADBAC7">  }</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> (</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;</span><span style="color:#8DDB8C">button</span><span style="color:#6CB6FF"> onClick</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">handleAdd</span><span style="color:#F47067">}</span><span style="color:#6CB6FF"> disabled</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">isAdding</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#F47067">      {</span><span style="color:#ADBAC7">isAdding </span><span style="color:#F47067">?</span><span style="color:#96D0FF"> 'Adding...'</span><span style="color:#F47067"> :</span><span style="color:#96D0FF"> `Add to Cart - $${</span><span style="color:#ADBAC7">price</span><span style="color:#96D0FF">}`</span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;/</span><span style="color:#8DDB8C">button</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  )</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>Notice how clean this is? The Server Component handles the heavy lifting of data fetching, and the Client Component only handles the specific piece of UI that needs to be interactive.</p>
<h3>Stop Passing Props</h3>
<p>One of the biggest mistakes I see (and made myself) is trying to pass complex objects or functions from a Server Component to a Client Component.</p>
<p>Remember: whatever crosses the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>"use client"</span></span></code></span> boundary has to be serialized and sent over the network. You can't pass functions, and passing massive JSON objects defeats the purpose of keeping the heavy lifting on the server.</p>
<p>Keep the props crossing the boundary as small and simple as possible.</p>
<p>Once I started treating Server Components like an API that returns UI instead of JSON, everything got easier. The errors went away, and my bundle sizes plummeted.</p>
<p>If you're struggling with RSCs, try reframing how you think about them. It makes all the difference.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Handling AI Fatigue as a Developer]]></title>
            <link>https://mustaquenadim.com/blog/ai-fatigue-dev</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/ai-fatigue-dev</guid>
            <pubDate>Tue, 17 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[We are swimming in new AI tools every week. Here is how I stay sane and actually get work done.]]></description>
            <content:encoded><![CDATA[<p>It feels like every week there's a new "game-changing" AI tool that promises to write all my code, fix all my bugs, and probably make me a coffee while it's at it. Honestly? It's exhausting.</p>
<p>As a developer, keeping up with the regular ecosystem was hard enough. Now, adding the constant pressure to adopt every new AI workflow is leading straight to burnout. I found myself spending more time trying to prompt an agent to build a component than it would have taken me to just write the React code myself.</p>
<p>Here's my current approach to staying sane:</p>
<p><strong>1. Pick One Tool and Master It</strong>
Instead of jumping between five different coding assistants, I stick to one. Learning its quirks, knowing when it hallucinates, and understanding its context window limitations is much more valuable than trying the flavor of the week.</p>
<p><strong>2. Use It for the Boring Stuff</strong>
I don't use AI to architecture my apps. I use it to write boilerplate, generate mock data, or write regex (because let's be real, nobody remembers how to write regex). Let the machine do the heavy lifting on the tedious parts so you can focus on the creative problem-solving.</p>
<p><strong>3. It's Okay to Just Write Code</strong>
Sometimes, opening a blank file and just typing out the logic yourself is the fastest, most reliable way to get things done. Don't feel guilty for not using AI for every single line of code.</p>
<p>We're in a transitional phase right now. The tools will get better, and the noise will eventually die down. Until then, protect your energy and remember why you fell in love with coding in the first place—building cool things.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Why CSS Variables Are Still Underrated]]></title>
            <link>https://mustaquenadim.com/blog/css-variables-design-systems</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/css-variables-design-systems</guid>
            <pubDate>Wed, 11 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Stop hardcoding hex values in your components. A robust token system built on CSS variables is the secret to a maintainable UI.]]></description>
            <content:encoded><![CDATA[<p>We live in an era of utility classes and CSS-in-JS. It's easy to get caught up in Tailwind classes or styled-component templates. But beneath whatever abstraction you're using, native CSS variables (Custom Properties) remain one of the most powerful and underutilized features of modern web development.</p>
<p>When I started building design systems, I’d see components littered with hardcoded values:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="css" data-theme="github-dark-dimmed"><code data-language="css" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#6CB6FF">.card</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#6CB6FF">  background-color</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">#ffffff</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#6CB6FF">  border-radius</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">8</span><span style="color:#F47067">px</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#6CB6FF">  box-shadow</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">0</span><span style="color:#6CB6FF"> 4</span><span style="color:#F47067">px</span><span style="color:#6CB6FF"> 6</span><span style="color:#F47067">px</span><span style="color:#6CB6FF"> rgba</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">0</span><span style="color:#ADBAC7">,</span><span style="color:#6CB6FF">0</span><span style="color:#ADBAC7">,</span><span style="color:#6CB6FF">0</span><span style="color:#ADBAC7">,</span><span style="color:#6CB6FF">0.1</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#6CB6FF">  padding</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">24</span><span style="color:#F47067">px</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>This works fine until you need a dark mode, or marketing decides the primary button should have more rounded corners, or you realize your padding is entirely inconsistent across the app.</p>
<h3>The Shift to Tokens</h3>
<p>Instead of values, think in <strong>tokens</strong>. A token is a named variable that represents a design decision.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="css" data-theme="github-dark-dimmed"><code data-language="css" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#6CB6FF">:root</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#768390">  /* Primitives (The palette) */</span></span>
<span data-line=""><span style="color:#F69D50">  --color-slate-900</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">#0f172a</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">  --color-white</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">#ffffff</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#ADBAC7">  </span></span>
<span data-line=""><span style="color:#F69D50">  --spacing-4</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">16</span><span style="color:#F47067">px</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F69D50">  --spacing-6</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">24</span><span style="color:#F47067">px</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#ADBAC7">  </span></span>
<span data-line=""><span style="color:#F69D50">  --radius-md</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">8</span><span style="color:#F47067">px</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#768390">  /* Semantics (The meaning) */</span></span>
<span data-line=""><span style="color:#F69D50">  --bg-surface</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">var</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">--color-white</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#F69D50">  --text-primary</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">var</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">--color-slate-900</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#F69D50">  --p-card</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">var</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">--spacing-6</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#F69D50">  --rounded-card</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">var</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">--radius-md</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">@media</span><span style="color:#ADBAC7"> (prefers-color-scheme: dark) {</span></span>
<span data-line=""><span style="color:#6CB6FF">  :root</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#F69D50">    --bg-surface</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">var</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">--color-slate-900</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#F69D50">    --text-primary</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">var</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">--color-white</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#ADBAC7">  }</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>Now, your component becomes incredibly dumb (which is what you want!):</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="css" data-theme="github-dark-dimmed"><code data-language="css" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#6CB6FF">.card</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#6CB6FF">  background-color</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">var</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">--bg-surface</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#6CB6FF">  color</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">var</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">--text-primary</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#6CB6FF">  border-radius</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">var</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">--rounded-card</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#6CB6FF">  padding</span><span style="color:#ADBAC7">: </span><span style="color:#6CB6FF">var</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">--p-card</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<h3>Why This Matters</h3>
<ol>
<li><strong>Dark Mode is Trivial:</strong> You don't rewrite component CSS. You just redefine the semantic tokens at the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>:root</span></span></code></span> level inside a media query (or a <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>.dark</span></span></code></span> class).</li>
<li><strong>Consistency by Default:</strong> You can't accidentally use <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>23px</span></span></code></span> padding if you're forced to use <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>var(--spacing-6)</span></span></code></span>.</li>
<li><strong>Theming:</strong> Want a high-contrast theme or a completely different brand palette for a white-label client? Just swap out the CSS file containing the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>:root</span></span></code></span> variables. The component logic doesn't change.</li>
</ol>
<p>CSS variables aren't just for colors. Use them for animation durations, z-indexes, typography scales, and spacing. Build your foundation on them, and everything else gets easier.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Making Peace with Next.js App Router Caching]]></title>
            <link>https://mustaquenadim.com/blog/nextjs-app-router-caching</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/nextjs-app-router-caching</guid>
            <pubDate>Tue, 10 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Next.js 14 caching is aggressive by default. Here's how I finally stopped fighting it and learned to love revalidatePath.]]></description>
            <content:encoded><![CDATA[<p>If you’ve moved to the Next.js App Router, you’ve probably hit the caching wall. You update a database row, refresh the page, and… nothing changes. The old data is staring right back at you.</p>
<p>For the first few weeks, I fought it. I sprinkled <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>export const dynamic = 'force-dynamic'</span></span></code></span> everywhere like salt just to make the pain stop. But that entirely defeats the purpose of the App Router's architecture.</p>
<p>Here’s what finally clicked for me:</p>
<h3>The Mindset Shift</h3>
<p>In the Pages router (<span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>getServerSideProps</span></span></code></span>), the mental model was: <em>fetch data on every request.</em></p>
<p>In the App Router, the default model is: <em>build it once, serve the static result forever.</em></p>
<p>Next.js assumes your data hasn't changed unless you explicitly tell it otherwise. It’s not a bug; it’s an incredibly aggressive feature designed to make your site fast by default.</p>
<h3>The Fix: On-Demand Revalidation</h3>
<p>Instead of forcing everything to be dynamic (which kills performance), keep the aggressive cache and just pop the balloon when you actually update data.</p>
<p>Server Actions are the perfect place for this.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="typescript" data-theme="github-dark-dimmed"><code data-language="typescript" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// actions.ts</span></span>
<span data-line=""><span style="color:#96D0FF">'use server'</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">import</span><span style="color:#ADBAC7"> { revalidatePath } </span><span style="color:#F47067">from</span><span style="color:#96D0FF"> 'next/cache'</span></span>
<span data-line=""><span style="color:#F47067">import</span><span style="color:#ADBAC7"> { db } </span><span style="color:#F47067">from</span><span style="color:#96D0FF"> '@/lib/db'</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> async</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> updatePost</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">id</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> string</span><span style="color:#ADBAC7">, </span><span style="color:#F69D50">content</span><span style="color:#F47067">:</span><span style="color:#6CB6FF"> string</span><span style="color:#ADBAC7">) {</span></span>
<span data-line=""><span style="color:#768390">  // 1. Do the mutation</span></span>
<span data-line=""><span style="color:#F47067">  await</span><span style="color:#ADBAC7"> db.post.</span><span style="color:#DCBDFB">update</span><span style="color:#ADBAC7">({</span></span>
<span data-line=""><span style="color:#ADBAC7">    where: { id },</span></span>
<span data-line=""><span style="color:#ADBAC7">    data: { content }</span></span>
<span data-line=""><span style="color:#ADBAC7">  })</span></span>
<span data-line=""><span style="color:#ADBAC7">  </span></span>
<span data-line=""><span style="color:#768390">  // 2. Tell Next.js the cache for this route is stale</span></span>
<span data-line=""><span style="color:#DCBDFB">  revalidatePath</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">`/posts/${</span><span style="color:#ADBAC7">id</span><span style="color:#96D0FF">}`</span><span style="color:#ADBAC7">)</span></span>
<span data-line=""><span style="color:#ADBAC7">  </span></span>
<span data-line=""><span style="color:#768390">  // If you want to blast the whole posts section:</span></span>
<span data-line=""><span style="color:#768390">  // revalidatePath('/posts', 'layout')</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>When this action runs, Next.js purges the cache for that specific path. The next person who visits (or the user who just submitted the form) gets a fresh server render. Everyone after that gets the <em>new</em> cached version.</p>
<h3>The Takeaway</h3>
<p>Stop fighting the cache. Let Next.js aggressively static-generate your pages, and use <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>revalidatePath</span></span></code></span> or <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>revalidateTag</span></span></code></span> right next to your database mutations. It takes a minute to get used to, but the performance benefits are massive.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[React Server Components: My Aha Moment]]></title>
            <link>https://mustaquenadim.com/blog/react-server-components-aha-moment</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/react-server-components-aha-moment</guid>
            <pubDate>Fri, 06 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why passing props from the server finally clicked for me, and why it's not just another hype train.]]></description>
            <content:encoded><![CDATA[<p>For the longest time, I looked at React Server Components (RSCs) with a mix of skepticism and fatigue. Another paradigm shift? Really? We just got used to hooks.</p>
<p>I kept reading the docs, watching the talks, and nodding along to terms like "zero bundle size" and "direct backend access." But it didn't really click until I had to build a dashboard that needed to aggregate data from three different crappy APIs.</p>
<p>In the old days (which was like, two years ago), my mental model was:</p>
<ol>
<li>Show a spinner.</li>
<li>Fire off three <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useEffect</span></span></code></span> fetches.</li>
<li>Handle the loading states, the error states, and the inevitable waterfall if one request depended on another.</li>
<li>Finally render the UI.</li>
</ol>
<p>The code was messy, full of <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>isLoading</span></span></code></span> flags, and frankly, annoying to maintain.</p>
<p>Then I tried it with an RSC.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="jsx" data-theme="github-dark-dimmed"><code data-language="jsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// This runs ON THE SERVER. Mind blown.</span></span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> default</span><span style="color:#F47067"> async</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> Dashboard</span><span style="color:#F69D50">() </span><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#ADBAC7"> [</span><span style="color:#6CB6FF">users</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">stats</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">alerts</span><span style="color:#ADBAC7">] </span><span style="color:#F47067">=</span><span style="color:#F47067"> await</span><span style="color:#6CB6FF"> Promise</span><span style="color:#ADBAC7">.</span><span style="color:#DCBDFB">all</span><span style="color:#ADBAC7">([</span></span>
<span data-line=""><span style="color:#DCBDFB">    fetchUsers</span><span style="color:#ADBAC7">(),</span></span>
<span data-line=""><span style="color:#DCBDFB">    fetchStats</span><span style="color:#ADBAC7">(),</span></span>
<span data-line=""><span style="color:#DCBDFB">    fetchAlerts</span><span style="color:#ADBAC7">(),</span></span>
<span data-line=""><span style="color:#ADBAC7">  ]);</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> (</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;</span><span style="color:#8DDB8C">div</span><span style="color:#6CB6FF"> className</span><span style="color:#F47067">=</span><span style="color:#96D0FF">"grid"</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">UserWidget</span><span style="color:#6CB6FF"> data</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">users</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> /></span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">StatsWidget</span><span style="color:#6CB6FF"> data</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">stats</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> /></span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">AlertsWidget</span><span style="color:#6CB6FF"> data</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">alerts</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> /></span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;/</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  );</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<p>That was it. The aha moment.</p>
<p>I wasn't managing state. I wasn't managing effects. I was just... writing a function that returned UI. It felt like writing PHP back in the day, but with the component model and ecosystem of React.</p>
<p>The beauty isn't just in the reduced client-side JavaScript (though that's nice). The beauty is in the simplified mental model. The server does the heavy lifting, gathers the data, and hands the client exactly what it needs to render—nothing more, nothing less.</p>
<p>It took me a while to stop reaching for <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useState</span></span></code></span> by default, but once you embrace the server-first mindset, it's hard to go back to the spinner life.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[The Trap of Premature Abstraction in React]]></title>
            <link>https://mustaquenadim.com/blog/react-simple-abstractions</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/react-simple-abstractions</guid>
            <pubDate>Fri, 06 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why creating reusable components too early often leads to a mess, and how to embrace duplication until the right abstraction emerges.]]></description>
            <content:encoded><![CDATA[<p>I used to have a rule: if I write the same UI code twice, extract it into a component. Sounds like good DRY (Don't Repeat Yourself) principles, right?</p>
<p>Turns out, this is a fantastic way to create a maintenance nightmare in React.</p>
<p>Here's the trap I kept falling into. I'd have a <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>UserProfileCard</span></span></code></span> and a <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>CompanyProfileCard</span></span></code></span>. They looked identical at first: avatar on the left, name in bold, subtext underneath. So, naturally, I'd abstract them into a <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>&#x3C;ProfileCard></span></span></code></span> component.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="tsx" data-theme="github-dark-dimmed"><code data-language="tsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">ProfileCard</span><span style="color:#ADBAC7"> </span></span>
<span data-line=""><span style="color:#6CB6FF">  image</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">data.avatar</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> </span></span>
<span data-line=""><span style="color:#6CB6FF">  title</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">data.name</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> </span></span>
<span data-line=""><span style="color:#6CB6FF">  subtitle</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">data.role</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> </span></span>
<span data-line=""><span style="color:#ADBAC7">/></span></span></code></pre></figure>
<p>Beautiful. Clean. Reusable.</p>
<p>Then the product requirements change.</p>
<p>The <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>UserProfileCard</span></span></code></span> needs an "Online" status indicator. The <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>CompanyProfileCard</span></span></code></span> needs a "Verified" badge next to the name. Now my clean abstraction needs props:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="tsx" data-theme="github-dark-dimmed"><code data-language="tsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">ProfileCard</span><span style="color:#ADBAC7"> </span></span>
<span data-line=""><span style="color:#6CB6FF">  image</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">data.avatar</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> </span></span>
<span data-line=""><span style="color:#6CB6FF">  title</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">data.name</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> </span></span>
<span data-line=""><span style="color:#6CB6FF">  subtitle</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">data.role</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> </span></span>
<span data-line=""><span style="color:#6CB6FF">  showOnlineStatus</span><span style="color:#F47067">={</span><span style="color:#6CB6FF">true</span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#6CB6FF">  isVerified</span><span style="color:#F47067">={</span><span style="color:#6CB6FF">false</span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#ADBAC7">/></span></span></code></pre></figure>
<p>A month later, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>CompanyProfileCard</span></span></code></span> needs to fetch its own specific data when clicked, but <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>UserProfileCard</span></span></code></span> shouldn't. Now I'm passing callbacks and specific flags. Before long, my <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>&#x3C;ProfileCard></span></span></code></span> is a 500-line behemoth of conditional logic, rendering totally different things based on the permutation of 15 different boolean props.</p>
<p>It's the classic "Aha!" moment: <strong>wrong abstraction is far worse than duplication.</strong></p>
<p>When we duplicate code, the cost is just typing more lines. We might have to update two places when styling changes. But when we create the wrong abstraction, the cost is cognitive overhead. Every time we need to add a feature to <em>one</em> use case, we have to carefully navigate the conditionals to ensure we don't break the <em>other</em> use cases.</p>
<p>My new rule is simple: <strong>Embrace duplication until the abstraction screams at you.</strong></p>
<p>I'll write the same layout three, four, even five times. I'll let the code sit there, slightly messy, slightly redundant. Over time, as features are added and requirements evolve, the <em>actual</em> shared concepts become obvious.</p>
<p>Maybe the shared abstraction isn't a <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>&#x3C;ProfileCard></span></span></code></span> at all. Maybe it's just a shared <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>&#x3C;Avatar></span></span></code></span> component, and the rest of the layout is unique to each domain. You only discover these boundaries by letting the duplication live long enough to tell you what it wants to be.</p>
<p>Don't be afraid to copy-paste. Sometimes it's the most architectural thing you can do.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[The Joy of Deleting Code]]></title>
            <link>https://mustaquenadim.com/blog/joy-of-deleting-code</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/joy-of-deleting-code</guid>
            <pubDate>Wed, 04 Mar 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Why removing lines of code is often more satisfying than writing them.]]></description>
            <content:encoded><![CDATA[<p>There’s a strange, almost visceral satisfaction that comes with deleting code.</p>
<p>When you first start out, productivity feels like it’s measured in lines written. The more you type, the more you’re "building." But as time goes on, you realize that code is a liability. Every line is something that needs to be maintained, debugged, and understood by the next person (who is often just you, six months later, wondering what on earth you were thinking).</p>
<p>I spent part of this week untangling a messy React component. It had grown organically over months—a new prop here, a quick workaround there. It was fragile.</p>
<p>Instead of adding another conditional to fix the latest bug, I decided to step back and rethink the abstraction. I pulled out a custom hook, simplified the state, and suddenly, I was able to delete 150 lines of complex, hard-to-follow logic.</p>
<p>The component works exactly the same, but it’s lighter now. Easier to read. Less likely to break.</p>
<p>Deleting code isn't just about making the file smaller; it's about clarifying intent. It’s the realization that you finally understand the problem well enough to solve it simply.</p>
<p>Next time you’re staring at a tangled mess, ask yourself: <em>What can I remove?</em> You might find that the best way to move forward is to leave less behind.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Understanding React Server Components vs. Client Components]]></title>
            <link>https://mustaquenadim.com/blog/understanding-react-server-components</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/understanding-react-server-components</guid>
            <pubDate>Tue, 24 Feb 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[A practical guide to understanding when and why to use Server vs. Client Components in modern React applications.]]></description>
            <content:encoded><![CDATA[<p>React Server Components (RSC) have fundamentally changed how we build React applications, especially when using frameworks like Next.js. For years, React was a purely client-side library. When a user visited a page, their browser downloaded the JavaScript bundle, executed it, and rendered the UI.</p>
<p>While effective, this approach meant sending large JavaScript bundles to the client and handling data fetching directly from the browser. Server Components change this dynamic entirely. Let's break down the differences and understand when to use each.</p>
<ul>
<li><a href="#what-are-server-components">What are Server Components?</a></li>
<li><a href="#what-are-client-components">What are Client Components?</a></li>
<li><a href="#key-differences-at-a-glance">Key Differences at a Glance</a></li>
<li><a href="#when-to-use-which">When to use which?</a></li>
</ul>
<hr>
<h2>What are Server Components?</h2>
<p>Server Components are React components that fetch data and render exclusively on the server. The resulting HTML and a special JSON representation of the UI are then sent to the client.</p>
<p>By default, in the Next.js App Router, all components are Server Components.</p>
<h3>Why are they useful?</h3>
<ol>
<li><strong>Zero Bundle Size:</strong> The JavaScript code for Server Components never reaches the client. This reduces the overall bundle size, leading to faster page loads.</li>
<li><strong>Direct Backend Access:</strong> You can safely fetch data directly from a database or use internal APIs without exposing sensitive information (like API keys) to the client.</li>
<li><strong>Automatic Code Splitting:</strong> Server Components automatically code-split your application by route.</li>
<li><strong>Caching:</strong> Server rendered results can be cached and reused across requests and users.</li>
</ol>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="tsx" data-theme="github-dark-dimmed"><code data-language="tsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#768390">// Example of a Server Component</span></span>
<span data-line=""><span style="color:#F47067">import</span><span style="color:#ADBAC7"> db </span><span style="color:#F47067">from</span><span style="color:#96D0FF"> '@/lib/db'</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> default</span><span style="color:#F47067"> async</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> UserProfile</span><span style="color:#F69D50">({ id }) </span><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#768390">  // We can fetch directly from the database!</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#6CB6FF"> user</span><span style="color:#F47067"> =</span><span style="color:#F47067"> await</span><span style="color:#ADBAC7"> db.user.</span><span style="color:#DCBDFB">findUnique</span><span style="color:#ADBAC7">({ where: { id } });</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> (</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">h1</span><span style="color:#ADBAC7">></span><span style="color:#F47067">{</span><span style="color:#ADBAC7">user.name</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">h1</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">p</span><span style="color:#ADBAC7">></span><span style="color:#F47067">{</span><span style="color:#ADBAC7">user.bio</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">p</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;/</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  );</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<h2>What are Client Components?</h2>
<p>Client Components are the traditional React components you are already familiar with. They render on the client (the browser) and can use state, effects, and event listeners.</p>
<p>To create a Client Component in modern React frameworks, you must explicitly opt-in by adding the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>"use client"</span></span></code></span> directive at the very top of your file.</p>
<h3>Why are they useful?</h3>
<ol>
<li><strong>Interactivity:</strong> You need Client Components for anything that requires user interaction (e.g., <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>onClick</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>onChange</span></span></code></span>).</li>
<li><strong>State and Lifecycle:</strong> If your component needs <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useState</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useEffect</span></span></code></span>, or <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useReducer</span></span></code></span>, it must be a Client Component.</li>
<li><strong>Browser APIs:</strong> If you need access to browser-specific APIs (like <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>window</span></span></code></span>, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>document</span></span></code></span>, or <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>localStorage</span></span></code></span>), you need a Client Component.</li>
</ol>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="tsx" data-theme="github-dark-dimmed"><code data-language="tsx" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#96D0FF">'use client'</span><span style="color:#ADBAC7">; </span><span style="color:#768390">// This directive is crucial!</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">import</span><span style="color:#ADBAC7"> { useState } </span><span style="color:#F47067">from</span><span style="color:#96D0FF"> 'react'</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">export</span><span style="color:#F47067"> default</span><span style="color:#F47067"> function</span><span style="color:#DCBDFB"> Counter</span><span style="color:#F69D50">() </span><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#F47067">  const</span><span style="color:#ADBAC7"> [</span><span style="color:#6CB6FF">count</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">setCount</span><span style="color:#ADBAC7">] </span><span style="color:#F47067">=</span><span style="color:#DCBDFB"> useState</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">0</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> (</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;</span><span style="color:#8DDB8C">button</span><span style="color:#6CB6FF"> onClick</span><span style="color:#F47067">={</span><span style="color:#ADBAC7">() </span><span style="color:#F47067">=></span><span style="color:#DCBDFB"> setCount</span><span style="color:#ADBAC7">(count </span><span style="color:#F47067">+</span><span style="color:#6CB6FF"> 1</span><span style="color:#ADBAC7">)</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">      Clicked </span><span style="color:#F47067">{</span><span style="color:#ADBAC7">count</span><span style="color:#F47067">}</span><span style="color:#ADBAC7"> times</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;/</span><span style="color:#8DDB8C">button</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  );</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<h2>Key Differences at a Glance</h2>
<table>
<thead>
<tr>
<th align="left">Feature</th>
<th align="left">Server Components</th>
<th align="left">Client Components</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left"><strong>Where it renders</strong></td>
<td align="left">Server only</td>
<td align="left">Client (and pre-rendered on server)</td>
</tr>
<tr>
<td align="left"><strong>Bundle size impact</strong></td>
<td align="left">Zero</td>
<td align="left">Adds to the JavaScript bundle</td>
</tr>
<tr>
<td align="left"><strong>Data Fetching</strong></td>
<td align="left">Direct DB/API access</td>
<td align="left">Must call an API endpoint</td>
</tr>
<tr>
<td align="left"><strong>State (<span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useState</span></span></code></span>)</strong></td>
<td align="left">❌ No</td>
<td align="left">✅ Yes</td>
</tr>
<tr>
<td align="left"><strong>Effects (<span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useEffect</span></span></code></span>)</strong></td>
<td align="left">❌ No</td>
<td align="left">✅ Yes</td>
</tr>
<tr>
<td align="left"><strong>Event Listeners</strong></td>
<td align="left">❌ No (<span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>onClick</span></span></code></span>, etc.)</td>
<td align="left">✅ Yes</td>
</tr>
<tr>
<td align="left"><strong>Browser APIs</strong></td>
<td align="left">❌ No (<span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>window</span></span></code></span>, etc.)</td>
<td align="left">✅ Yes</td>
</tr>
</tbody>
</table>
<h2>When to use which?</h2>
<p>A good rule of thumb is to <strong>default to Server Components</strong> until you absolutely need a Client Component.</p>
<p>Think of Server Components as the "skeleton" of your page, responsible for fetching data and rendering static content. Think of Client Components as the "muscles," added only where interactivity or state is required (like a button, a form, or an interactive chart).</p>
<p>By combining both effectively, you can build applications that are incredibly fast, secure, and highly interactive.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Dependencies vs DevDependencies: What Every Beginner Should Know]]></title>
            <link>https://mustaquenadim.com/blog/difference-between-dependencies-and-dev-dependencies</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/difference-between-dependencies-and-dev-dependencies</guid>
            <pubDate>Sun, 26 May 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Discover the key differences between functions and methods in JavaScript]]></description>
            <content:encoded><![CDATA[<p>As a curious programmer, you might come across the terms "dependencies" and "devDependencies" when working on JavaScript or Node.js projects. These terms can seem confusing at first, but they are essential concepts to understand when managing your project's libraries and tools. In this blog, we'll break down what dependencies and devDependencies are, why they matter, and provide a simple example to illustrate the difference.</p>
<ul>
<li><a href="#dependencies">Dependencies</a></li>
<li><a href="#devdependencies">DevDependencies</a></li>
<li><a href="#example">Example</a></li>
<li><a href="#why-it-matters">Why It Matters</a></li>
<li><a href="#comparison-table">Comparison Table</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul>
<h2>Dependencies </h2>
<p>Dependencies are the libraries or packages that your project needs to run in production. These are the essential building blocks that your application relies on to function correctly. Without these dependencies, your application would either not run at all or fail to perform its intended tasks.</p>
<p>For example, if you are building a web application using the Express framework, Express would be a dependency because your application needs it to handle HTTP requests and responses.</p>
<h2>DevDependencies </h2>
<p>On the other hand, devDependencies are the libraries or packages that are only needed during the development phase. These are tools that help you write, test, and maintain your code but are not required when your application is running in production. They can include testing frameworks, code linters, and build tools.</p>
<p>For instance, if you use Jest for testing your code, Jest would be a devDependency because you only need it to test your application, not to run it in production.</p>
<h2>Example </h2>
<p>Let's look at a practical example to illustrate the difference. Suppose you are creating a simple Node.js web application using Express and you want to use Jest for testing.</p>
<ol>
<li><strong>Setting Up Your Project:</strong></li>
</ol>
<p>First, you would initialize your project using npm (Node Package Manager):</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="bash" data-theme="github-dark-dimmed"><code data-language="bash" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F69D50">npm</span><span style="color:#96D0FF"> init</span><span style="color:#6CB6FF"> -y</span></span></code></pre></figure>
<p>This command creates a <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>package.json</span></span></code></span> file, which is used to manage your project's dependencies.</p>
<ol start="2">
<li><strong>Installing Dependencies:</strong></li>
</ol>
<p>Next, you install Express as a dependency because your application needs it to handle HTTP requests:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="bash" data-theme="github-dark-dimmed"><code data-language="bash" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F69D50">npm</span><span style="color:#96D0FF"> install</span><span style="color:#96D0FF"> express</span></span></code></pre></figure>
<p>This command adds Express to the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>dependencies</span></span></code></span> section of your <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>package.json</span></span></code></span> file.</p>
<ol start="3">
<li><strong>Installing DevDependencies:</strong></li>
</ol>
<p>Then, you install Jest as a devDependency because you only need it for testing during development:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="bash" data-theme="github-dark-dimmed"><code data-language="bash" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F69D50">npm</span><span style="color:#96D0FF"> install</span><span style="color:#96D0FF"> jest</span><span style="color:#6CB6FF"> --save-dev</span></span></code></pre></figure>
<p>This command adds Jest to the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>devDependencies</span></span></code></span> section of your <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>package.json</span></span></code></span> file.</p>
<p>Your <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>package.json</span></span></code></span> file would now look something like this:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="json" data-theme="github-dark-dimmed"><code data-language="json" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#ADBAC7">{</span></span>
<span data-line=""><span style="color:#8DDB8C">  "name"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"my-node-app"</span><span style="color:#ADBAC7">,</span></span>
<span data-line=""><span style="color:#8DDB8C">  "version"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"1.0.0"</span><span style="color:#ADBAC7">,</span></span>
<span data-line=""><span style="color:#8DDB8C">  "main"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"index.js"</span><span style="color:#ADBAC7">,</span></span>
<span data-line=""><span style="color:#8DDB8C">  "license"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"MIT"</span><span style="color:#ADBAC7">,</span></span>
<span data-line=""><span style="color:#8DDB8C">  "dependencies"</span><span style="color:#ADBAC7">: {</span></span>
<span data-line=""><span style="color:#8DDB8C">    "express"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"^4.17.1"</span></span>
<span data-line=""><span style="color:#ADBAC7">  },</span></span>
<span data-line=""><span style="color:#8DDB8C">  "devDependencies"</span><span style="color:#ADBAC7">: {</span></span>
<span data-line=""><span style="color:#8DDB8C">    "jest"</span><span style="color:#ADBAC7">: </span><span style="color:#96D0FF">"^26.6.3"</span></span>
<span data-line=""><span style="color:#ADBAC7">  }</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<h2>Why It Matters </h2>
<p>Understanding the difference between dependencies and devDependencies is crucial for several reasons:</p>
<ul>
<li><strong>Optimizing Production Builds:</strong> By separating devDependencies from dependencies, you ensure that your production build only includes the necessary libraries, making it more lightweight and efficient.</li>
<li><strong>Security:</strong> Minimizing the number of packages in your production environment reduces potential security vulnerabilities.</li>
<li><strong>Maintenance:</strong> Clear separation helps in managing and updating packages more efficiently, as you know which packages are needed for development versus production.</li>
</ul>
<h2>Comparison Table </h2>
<p>To further clarify the differences, here's a comparison table:</p>
<table>
<thead>
<tr>
<th>Aspect</th>
<th>Dependencies</th>
<th>DevDependencies</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Purpose</strong></td>
<td>Essential for the application to run in production</td>
<td>Only needed during development and testing</td>
</tr>
<tr>
<td><strong>Usage Environment</strong></td>
<td>Required in both development and production</td>
<td>Required only in the development environment</td>
</tr>
<tr>
<td><strong>Installation Command</strong></td>
<td><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>npm install &#x3C;package></span></span></code></span></td>
<td><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>npm install &#x3C;package> --save-dev</span></span></code></span></td>
</tr>
<tr>
<td><strong>Example Libraries</strong></td>
<td>Express, React, Axios</td>
<td>Jest, ESLint, Webpack</td>
</tr>
<tr>
<td><strong>Package.json Location</strong></td>
<td><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>dependencies</span></span></code></span> section</td>
<td><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>devDependencies</span></span></code></span> section</td>
</tr>
<tr>
<td><strong>Impact on Build Size</strong></td>
<td>Increases the size of the production build</td>
<td>Does not affect the production build size</td>
</tr>
<tr>
<td><strong>Security Considerations</strong></td>
<td>Essential for running the application, so needs regular security updates</td>
<td>Less critical for production security, but important for development process integrity</td>
</tr>
<tr>
<td><strong>Impact on Deployment</strong></td>
<td>Included in the deployment package</td>
<td>Not included in the deployment package</td>
</tr>
<tr>
<td><strong>Command for Installation in Production</strong></td>
<td><span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>npm install --only=production</span></span></code></span></td>
<td>Not installed with <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>npm install --only=production</span></span></code></span></td>
</tr>
</tbody>
</table>
<h3>Conclusion </h3>
<p>In summary, dependencies are the essential libraries your project needs to run in production, while devDependencies are the tools and libraries needed only during development. By properly managing these two types of dependencies, you can create more efficient, secure, and maintainable applications.</p>
<p>Remember, the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>package.json</span></span></code></span> file is your project's roadmap for dependencies. Keeping it organized and well-maintained will save you a lot of headaches down the road as your projects grow and evolve.</p>
<p>Happy coding!</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[How to use ChatGPT Plus GPT-4 Model for free]]></title>
            <link>https://mustaquenadim.com/blog/how-to-use-chatgpt-4-for-free</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/how-to-use-chatgpt-4-for-free</guid>
            <pubDate>Sat, 25 May 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[ChatGPT-4 is completely free in other sites]]></description>
            <content:encoded><![CDATA[<p>OpenAI, an American artificial intelligence (AI) research company released an AI chatbot named ChatGPT on November 2022. After releasing ChatGPT, it crossed over a million user within 5 days. And reached 100 million users within 2 months. On March 14, 2023 OpenAI released GPT-4 (latest) which is a families of large language models (LLMs) comes with improved features and capabilities, including multimodal capabilities for interpreting both text and image inputs, exceptional performance in reasoning tests, and support for over 26 different languages.</p>
<p>However, it is not accessible to free users. It is available only via API and ChatGPT premium users for 20$. But today I'll guide you how you can use GPT-4 AI language model for free. Let's jump into the guide.</p>
<h2>1. <a href="https://www.forefront.ai/">ForeFront</a></h2>
<p><img src="/images/posts/how-to-use-chatgpt-4-for-free/forefront.png" alt="Forefront"></p>
<p>Forefront Chat is a new tool launched by Forefront AI that offers free access to GPT-4, but recently you can only send 5 messages every 3 hours. It provides more people with the opportunity to try out this cutting-edge technology. To access GPT-4, all you need to do is sign up for free on the Forefront Chat website. Apart from GPT-4, users can also try image generation, custom personas, shareable chats, and more on the platform.</p>
<h2>2. <a href="https://ora.ai/">Ora</a></h2>
<p><img src="/images/posts/how-to-use-chatgpt-4-for-free/ora.png" alt="Ora"></p>
<p>Ora is a web platform that allows you to build LLM apps in a shareable chat interface. The developer is now providing users with the opportunity to explore <a href="https://ora.ai/openai/gpt4">ChatGPT 4</a> for free, but has limited the usage to 1 message per day due to high demand.</p>
<h2>3. <a href="https://copilot.microsoft.com/">Microsoft Copilot</a></h2>
<p><img src="/images/posts/how-to-use-chatgpt-4-for-free/bing-chat.png" alt="Microsoft Copilot"></p>
<p>Microsoft Copilot is another option to access GPT-4 for free. You can send unlimited messages for free. Bing AI has announced that it is already running on the GPT-4 model, also known as "Prometheus," and has some additional features, such as the ability to generate images with a simple prompt and provide cited sources of information.</p>
<h2>4. <a href="https://huggingface.co/spaces/ysharma/ChatGPT4">HuggingFace</a></h2>
<p><img src="/images/posts/how-to-use-chatgpt-4-for-free/huggingface.png" alt="HuggingFace"></p>
<p>If you're looking for another way to experiment with ChatGPT 4, check out the free bot built by developer Yuvraj Sharma on HuggingFace. You don't even need your own OpenAI API key to use it, as GPT-4 API access is provided by HuggingFace to its community. It also has multilingual support and a token limit of 4096.</p>
<h2>5. <a href="https://nat.dev/">Nat.dev</a></h2>
<p><img src="/images/posts/how-to-use-chatgpt-4-for-free/open-playground.png" alt="Nat.dev Open Playground"></p>
<p>Former CEO of GitHub, Nat Friedman has created an amazing tool to compare different language models offered by AI companies all around the world. It is a tool that can show you how ChatGPT 4 stacked up against other models or just let you explore the incredible GPT-4 model on your own.</p>
<h2>6. <a href="https://www.perplexity.ai/">Perplexity</a></h2>
<p><img src="/images/posts/how-to-use-chatgpt-4-for-free/perplexity.png" alt="Perplexity"></p>
<p>Perplexity AI is a web crawler that uses machine learning to generate general answers to your queries and then offer a series of website links. The links are to websites that the AI thinks are relevant to your query. It is a new AI chat tool that acts as an extremely powerful search engine. When a user inputs a question, the model scours the internet to give an answer. And what’s great about this tool, is its ability to display the source of the information it provides². It unlocks the power of knowledge with information discovery and sharing. It was built using the same model as Chat GPT (GPT-3), however, offers a very different service.</p>
<h2>7. <a href="https://poe.com/">Poe</a></h2>
<p><img src="/images/posts/how-to-use-chatgpt-4-for-free/poe.png" alt="Poe"></p>
<p>Poe is a chatbot assistant that lets you ask questions, get instant answers, and have back-and-forth conversations with AI. It gives access to several bots powered by OpenAI and Anthropic. Poe Fast AI Chatbot Assistant is designed for users 12+ and provides a fast, helpful AI chat experience. Quora launched a platform called Poe that lets people ask questions, get instant answers and have a back-and-forth conversation with AI. Poe offers access to ChatGPT and GPT-4; Claude Plus and Claude Instant, two different bots from Anthropic; Sage, also based on ChatGPT; and Dragonfly, a model using a different method than the others.</p>
<p>As technology continues to evolve, it's exciting to imagine what other groundbreaking advancements in AI are on the horizon. So, what are you waiting for? Dive into the world of ChatGPT-4 and discover its wonder for yourself!</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[How to Disable Right-Click in a React Application]]></title>
            <link>https://mustaquenadim.com/blog/disable-right-click-in-a-react-app</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/disable-right-click-in-a-react-app</guid>
            <pubDate>Thu, 18 Apr 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Disable Right-Click in a React Application]]></description>
            <content:encoded><![CDATA[<p>Right-click functionality can be useful in many scenarios, but there are cases where you might want to disable it. For instance, you may want to prevent users from copying content or accessing context menus on certain elements. In this blog post, we’ll explore how to achieve this in a React application.</p>
<h2>Method: Using the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>onContextMenu</span></span></code></span> Event</h2>
<p>The onContextMenu event is triggered when a user right-clicks on an element. By calling the preventDefault() method on this event, we can prevent the default context menu from appearing. Let’s see how to implement this in a React component:</p>
<h3>1. Create a React Component</h3>
<p>First, create a new React component (or use an existing one). For demonstration purposes, let’s call it <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>MyComponent</span></span></code></span>.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="js" data-theme="github-dark-dimmed"><code data-language="js" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F47067">import</span><span style="color:#ADBAC7"> React, { useEffect } </span><span style="color:#F47067">from</span><span style="color:#96D0FF"> 'react'</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">function</span><span style="color:#DCBDFB"> MyComponent</span><span style="color:#ADBAC7">() {</span></span>
<span data-line=""><span style="color:#DCBDFB">  useEffect</span><span style="color:#ADBAC7">(() </span><span style="color:#F47067">=></span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#F47067">    function</span><span style="color:#DCBDFB"> handleContextMenu</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">e</span><span style="color:#ADBAC7">) {</span></span>
<span data-line=""><span style="color:#ADBAC7">      e.</span><span style="color:#DCBDFB">preventDefault</span><span style="color:#ADBAC7">(); </span><span style="color:#768390">// Prevents the default right-click menu from appearing</span></span>
<span data-line=""><span style="color:#ADBAC7">    }</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#768390">    // Add the event listener to the component's root element</span></span>
<span data-line=""><span style="color:#F47067">    const</span><span style="color:#6CB6FF"> rootElement</span><span style="color:#F47067"> =</span><span style="color:#ADBAC7"> document.</span><span style="color:#DCBDFB">getElementById</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">'my-component'</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#ADBAC7">    rootElement.</span><span style="color:#DCBDFB">addEventListener</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">'contextmenu'</span><span style="color:#ADBAC7">, handleContextMenu);</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#768390">    // Remove the event listener when the component is unmounted</span></span>
<span data-line=""><span style="color:#F47067">    return</span><span style="color:#ADBAC7"> () </span><span style="color:#F47067">=></span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#ADBAC7">      rootElement.</span><span style="color:#DCBDFB">removeEventListener</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">'contextmenu'</span><span style="color:#ADBAC7">, handleContextMenu);</span></span>
<span data-line=""><span style="color:#ADBAC7">    };</span></span>
<span data-line=""><span style="color:#ADBAC7">  }, []);</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> &#x3C;</span><span style="color:#8DDB8C">div</span><span style="color:#6CB6FF"> id</span><span style="color:#F47067">=</span><span style="color:#96D0FF">"my-component"</span><span style="color:#ADBAC7">></span><span style="color:#F47067">{</span><span style="color:#768390">/* Your component's content */</span><span style="color:#F47067">}</span><span style="color:#ADBAC7">&#x3C;/</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">>;</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span></code></pre></figure>
<h3>2. Explanation</h3>
<ul>
<li>We use the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>useEffect</span></span></code></span> hook to add and remove the event listener when the component is mounted and unmounted, respectively.</li>
<li>The <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>handleContextMenu</span></span></code></span> function is called when the “contextmenu” event is triggered. It prevents the default behavior of the event using <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>preventDefault</span></span></code></span>.</li>
<li>Replace the content inside the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>div</span></span></code></span> with your actual component content.</li>
</ul>
<h3>3. Usage</h3>
<p>Simply include the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>MyComponent</span></span></code></span> in your application where needed:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="js" data-theme="github-dark-dimmed"><code data-language="js" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F47067">import</span><span style="color:#ADBAC7"> React </span><span style="color:#F47067">from</span><span style="color:#96D0FF"> 'react'</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F47067">import</span><span style="color:#ADBAC7"> ReactDOM </span><span style="color:#F47067">from</span><span style="color:#96D0FF"> 'react-dom'</span><span style="color:#ADBAC7">;</span></span>
<span data-line=""><span style="color:#F47067">import</span><span style="color:#ADBAC7"> MyComponent </span><span style="color:#F47067">from</span><span style="color:#96D0FF"> './MyComponent'</span><span style="color:#ADBAC7">; </span><span style="color:#768390">// Adjust the path as needed</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">function</span><span style="color:#DCBDFB"> App</span><span style="color:#ADBAC7">() {</span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> (</span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#F47067">      {</span><span style="color:#768390">/* Other components */</span><span style="color:#F47067">}</span></span>
<span data-line=""><span style="color:#ADBAC7">      &#x3C;</span><span style="color:#8DDB8C">MyComponent</span><span style="color:#ADBAC7"> /></span></span>
<span data-line=""><span style="color:#ADBAC7">    &#x3C;/</span><span style="color:#8DDB8C">div</span><span style="color:#ADBAC7">></span></span>
<span data-line=""><span style="color:#ADBAC7">  );</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#ADBAC7">ReactDOM.</span><span style="color:#DCBDFB">render</span><span style="color:#ADBAC7">(&#x3C;</span><span style="color:#8DDB8C">App</span><span style="color:#ADBAC7"> />, document.</span><span style="color:#DCBDFB">getElementById</span><span style="color:#ADBAC7">(</span><span style="color:#96D0FF">'root'</span><span style="color:#ADBAC7">));</span></span></code></pre></figure>
<h2>Considerations</h2>
<ul>
<li>Disabling the right-click menu should be used thoughtfully. It can impact user experience, especially if users expect certain interactions.</li>
<li>Use this technique judiciously based on your application’s requirements.</li>
</ul>
<p>Feel free to customize the component and integrate it into your React project. Remember to test thoroughly to ensure it meets your needs.</p>
<p>Happy coding! 😊🚀</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Understanding Inline, Inline-Block, and Block Elements in HTML]]></title>
            <link>https://mustaquenadim.com/blog/inline-inline-block-and-block-elements-in-html</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/inline-inline-block-and-block-elements-in-html</guid>
            <pubDate>Sun, 02 Jul 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Unlock the secrets of inline, inline-block, and block elements in HTML]]></description>
            <content:encoded><![CDATA[<p>When working with HTML, it's crucial to understand the different display properties of elements.</p>
<h2>Inline Elements</h2>
<p>Inline elements are those that do not create line breaks and flow with the surrounding content.</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="html" data-theme="github-dark-dimmed"><code data-language="html" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#ADBAC7">&#x3C;</span><span style="color:#8DDB8C">p</span><span style="color:#ADBAC7">>Hello&#x3C;/</span><span style="color:#8DDB8C">p</span><span style="color:#ADBAC7">></span></span></code></pre></figure>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
        <item>
            <title><![CDATA[Difference between Function and Method in JavaScript]]></title>
            <link>https://mustaquenadim.com/blog/difference-between-function-and-method-in-javascript</link>
            <guid isPermaLink="false">https://mustaquenadim.com/blog/difference-between-function-and-method-in-javascript</guid>
            <pubDate>Sat, 01 Jul 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[Discover the key differences between functions and methods in JavaScript]]></description>
            <content:encoded><![CDATA[<p>When working with JavaScript, it's crucial to grasp the distinction between functions and methods. While they might seem similar at first, they serve different purposes and have specific use cases. In this article, we'll explore the key differences between functions and methods in JavaScript, accompanied by beginner-friendly examples.</p>
<p>The objective of this article is to provide a clear understanding of how functions and methods differ and when to use each.</p>
<ul>
<li><a href="#functions">Functions</a></li>
<li><a href="#methods">Methods</a></li>
<li><a href="#conclusion">Conclusion</a></li>
<li><a href="#resources">Resources</a></li>
</ul>
<h2>Functions </h2>
<p>In JavaScript, functions are reusable blocks of code designed to perform a specific task. They are independent entities and can be invoked from various parts of your code. Here's an example:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="javascript" data-theme="github-dark-dimmed"><code data-language="javascript" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F47067">function</span><span style="color:#DCBDFB"> calculateArea</span><span style="color:#ADBAC7">(</span><span style="color:#F69D50">length</span><span style="color:#ADBAC7">, </span><span style="color:#F69D50">width</span><span style="color:#ADBAC7">) {</span></span>
<span data-line=""><span style="color:#F47067">  return</span><span style="color:#ADBAC7"> length </span><span style="color:#F47067">*</span><span style="color:#ADBAC7"> width;</span></span>
<span data-line=""><span style="color:#ADBAC7">}</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">const</span><span style="color:#6CB6FF"> rectangleArea</span><span style="color:#F47067"> =</span><span style="color:#DCBDFB"> calculateArea</span><span style="color:#ADBAC7">(</span><span style="color:#6CB6FF">5</span><span style="color:#ADBAC7">, </span><span style="color:#6CB6FF">3</span><span style="color:#ADBAC7">);</span></span>
<span data-line=""><span style="color:#ADBAC7">console.</span><span style="color:#DCBDFB">log</span><span style="color:#ADBAC7">(rectangleArea); </span><span style="color:#768390">// Output: 15</span></span></code></pre></figure>
<p>In the above code, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>calculateArea</span></span></code></span> function takes <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>length</span></span></code></span> and <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>width</span></span></code></span> as parameters and returns the calculated area. The function is invoked outside of any specific object, making it a standalone function.</p>
<h2>Methods </h2>
<p>Methods, on the other hand, are functions that are associated with objects. They are defined within the object's scope and can access the object's properties. Let's consider the following example:</p>
<figure data-rehype-pretty-code-figure=""><pre style="background-color:#22272e;color:#adbac7" tabindex="0" data-language="javascript" data-theme="github-dark-dimmed"><code data-language="javascript" data-theme="github-dark-dimmed" style="display: grid;"><span data-line=""><span style="color:#F47067">const</span><span style="color:#6CB6FF"> rectangle</span><span style="color:#F47067"> =</span><span style="color:#ADBAC7"> {</span></span>
<span data-line=""><span style="color:#ADBAC7">  length: </span><span style="color:#6CB6FF">5</span><span style="color:#ADBAC7">,</span></span>
<span data-line=""><span style="color:#ADBAC7">  width: </span><span style="color:#6CB6FF">3</span><span style="color:#ADBAC7">,</span></span>
<span data-line=""><span style="color:#DCBDFB">  calculateArea</span><span style="color:#ADBAC7">: </span><span style="color:#F47067">function</span><span style="color:#ADBAC7"> () {</span></span>
<span data-line=""><span style="color:#F47067">    return</span><span style="color:#6CB6FF"> this</span><span style="color:#ADBAC7">.</span><span style="color:#6CB6FF">length</span><span style="color:#F47067"> *</span><span style="color:#6CB6FF"> this</span><span style="color:#ADBAC7">.width;</span></span>
<span data-line=""><span style="color:#ADBAC7">  },</span></span>
<span data-line=""><span style="color:#ADBAC7">};</span></span>
<span data-line=""> </span>
<span data-line=""><span style="color:#F47067">const</span><span style="color:#6CB6FF"> rectangleArea</span><span style="color:#F47067"> =</span><span style="color:#ADBAC7"> rectangle.</span><span style="color:#DCBDFB">calculateArea</span><span style="color:#ADBAC7">();</span></span>
<span data-line=""><span style="color:#ADBAC7">console.</span><span style="color:#DCBDFB">log</span><span style="color:#ADBAC7">(rectangleArea); </span><span style="color:#768390">// Output: 15</span></span></code></pre></figure>
<p>In this code snippet, <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>calculateArea</span></span></code></span> is a method defined within the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>rectangle</span></span></code></span> object. It utilizes the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>length</span></span></code></span> and <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>width</span></span></code></span> properties of the object using the <span data-rehype-pretty-code-figure=""><code data-language="plaintext" data-theme="github-dark-dimmed" style="background-color:#22272e;color:#adbac7"><span data-line=""><span>this</span></span></code></span> keyword.</p>
<blockquote>
<p>Use functions when you want to create reusable blocks of code that can be invoked from anywhere.
Utilize methods when you want to define behavior specific to an object, accessing its properties and other methods.</p>
</blockquote>
<h2>Conclusion </h2>
<p>In conclusion, understanding the difference between functions and methods is essential in JavaScript. Functions are standalone blocks of code, while methods are functions associated with objects. By knowing when to use each, you can write more efficient and organized code.</p>
<h2>Resources </h2>
<ul>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript">https://developer.mozilla.org/en-US/docs/Web/JavaScript</a></li>
<li><a href="https://eloquentjavascript.net/">https://eloquentjavascript.net/</a></li>
</ul>
<p>If you found this article helpful, feel free to share it with fellow developers and subscribe to our blog for more informative content.</p>]]></content:encoded>
            <author>Mustaque Nadim</author>
        </item>
    </channel>
</rss>