<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gavin Cettolo</title>
    <description>The latest articles on DEV Community by Gavin Cettolo (@gavincettolo).</description>
    <link>https://dev.to/gavincettolo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3353748%2Fe37c0e94-b63c-4a02-88bc-ad4e130a2ee5.jpg</url>
      <title>DEV Community: Gavin Cettolo</title>
      <link>https://dev.to/gavincettolo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gavincettolo"/>
    <language>en</language>
    <item>
      <title>The Strategy Pattern in JavaScript: Replace Messy If-Else Logic With Clean Code</title>
      <dc:creator>Gavin Cettolo</dc:creator>
      <pubDate>Tue, 14 Apr 2026 07:30:00 +0000</pubDate>
      <link>https://dev.to/gavincettolo/the-strategy-pattern-in-javascript-replace-messy-if-else-logic-with-clean-code-45ap</link>
      <guid>https://dev.to/gavincettolo/the-strategy-pattern-in-javascript-replace-messy-if-else-logic-with-clean-code-45ap</guid>
      <description>&lt;p&gt;A while ago, I opened a file and immediately knew something was off.&lt;/p&gt;

&lt;p&gt;Not because it was broken.&lt;br&gt;
Not because it was complex.&lt;/p&gt;

&lt;p&gt;But because it had &lt;em&gt;that shape&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You know the one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// something else&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// another thing&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// fallback&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It worked.&lt;/p&gt;

&lt;p&gt;But every time we needed to add a new case, we had to go back into that block and make it just a bit worse.&lt;/p&gt;

&lt;p&gt;And that’s when I realized:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This isn’t just messy code. This is a scaling problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s fix it.&lt;/p&gt;




&lt;h4&gt;
  
  
  TL;DR
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Long &lt;code&gt;if-else&lt;/code&gt; chains are a signal that your logic &lt;strong&gt;doesn’t scale well&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The Strategy Pattern helps you &lt;strong&gt;encapsulate behaviors and swap them easily&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;In JavaScript, you don’t need heavy OOP: &lt;strong&gt;functions are often enough&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ul&gt;
&lt;li&gt;The Problem: The If-Else Monster&lt;/li&gt;
&lt;li&gt;A Real Example: Payment Methods&lt;/li&gt;
&lt;li&gt;Why This Doesn’t Scale&lt;/li&gt;
&lt;li&gt;Introducing the Strategy Pattern&lt;/li&gt;
&lt;li&gt;Step-by-Step Refactoring&lt;/li&gt;
&lt;li&gt;Final Result: Clean and Extensible&lt;/li&gt;
&lt;li&gt;Using TypeScript for Safer Strategies&lt;/li&gt;
&lt;li&gt;Optional: Class-Based Strategy&lt;/li&gt;
&lt;li&gt;When to Use (and Not Use) Strategy&lt;/li&gt;
&lt;li&gt;Final Thoughts&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Problem: The If-Else Monster
&lt;/h2&gt;

&lt;p&gt;At first, &lt;code&gt;if-else&lt;/code&gt; feels fine.&lt;/p&gt;

&lt;p&gt;It’s simple.&lt;br&gt;
It’s readable.&lt;br&gt;
It gets the job done.&lt;/p&gt;

&lt;p&gt;Until it doesn’t.&lt;/p&gt;

&lt;p&gt;The moment your logic starts growing based on types, modes, or variants, things start getting messy.&lt;/p&gt;

&lt;p&gt;And more importantly: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;every new feature requires modifying existing logic&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s the real problem.&lt;/p&gt;


&lt;h2&gt;
  
  
  A Real Example: Payment Methods
&lt;/h2&gt;

&lt;p&gt;Let’s say you’re building a checkout system.&lt;/p&gt;

&lt;p&gt;You need to handle multiple payment methods:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;credit card&lt;/li&gt;
&lt;li&gt;PayPal&lt;/li&gt;
&lt;li&gt;bank transfer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A typical implementation might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;credit-card&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Processing credit card payment:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// card logic&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;paypal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Processing PayPal payment:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// paypal logic&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bank-transfer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Processing bank transfer:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// bank logic&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unsupported payment method&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works, but you can already feel the tension.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Doesn’t Scale
&lt;/h2&gt;

&lt;p&gt;The issue isn’t the code itself.&lt;/p&gt;

&lt;p&gt;It’s how it evolves.&lt;/p&gt;

&lt;p&gt;Every time you add a new payment method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you modify this function&lt;/li&gt;
&lt;li&gt;you increase its complexity&lt;/li&gt;
&lt;li&gt;you risk breaking existing logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After a few iterations, you end up with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;long functions&lt;/li&gt;
&lt;li&gt;duplicated patterns&lt;/li&gt;
&lt;li&gt;fragile logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is exactly where the &lt;strong&gt;Strategy Pattern&lt;/strong&gt; shines.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introducing the Strategy Pattern
&lt;/h2&gt;

&lt;p&gt;The idea is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Instead of having one function decide how to do everything,&lt;br&gt;
delegate each behavior to a separate “strategy”.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each strategy handles one case.&lt;/p&gt;

&lt;p&gt;The main function just selects which one to use.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;replace conditionals with a &lt;strong&gt;lookup-based approach&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step-by-Step Refactoring
&lt;/h2&gt;

&lt;p&gt;Let’s improve the previous example step by step.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 1: Extract behaviors
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;payWithCreditCard&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Processing credit card payment:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;payWithPaypal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Processing PayPal payment:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;payWithBankTransfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Processing bank transfer:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each function now has a clear responsibility.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 2: Create a strategy map
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paymentStrategies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;credit-card&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payWithCreditCard&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;paypal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payWithPaypal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bank-transfer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payWithBankTransfer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This replaces the &lt;code&gt;if-else&lt;/code&gt; chain with a simple lookup.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 3: Simplify the main function
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;paymentStrategies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unsupported payment method&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No branching logic.&lt;/p&gt;

&lt;p&gt;Just delegation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Result: Clean and Extensible
&lt;/h2&gt;

&lt;p&gt;Now adding a new payment method is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;payWithCrypto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Processing crypto payment:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;paymentStrategies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;payWithCrypto&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No need to modify existing logic.&lt;/p&gt;

&lt;p&gt;No risk of breaking unrelated behavior.&lt;/p&gt;

&lt;p&gt;👉 This is the real benefit: &lt;strong&gt;open for extension, closed for modification&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Using TypeScript for Safer Strategies
&lt;/h2&gt;

&lt;p&gt;So far, everything works perfectly in JavaScript.&lt;/p&gt;

&lt;p&gt;And thanks to this guard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unsupported payment method&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;invalid inputs are handled safely.&lt;/p&gt;

&lt;p&gt;However, the error is still detected at runtime.&lt;/p&gt;

&lt;p&gt;With TypeScript, we can catch the same issue earlier, before the code even runs.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 1: Define allowed methods
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PaymentMethod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;credit-card&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;paypal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bank-transfer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now only valid methods are allowed.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 2: Type the strategies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;PaymentStrategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paymentStrategies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PaymentMethod&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PaymentStrategy&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;credit-card&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payWithCreditCard&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;paypal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payWithPaypal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bank-transfer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;payWithBankTransfer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now TypeScript guarantees:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;every method has a strategy&lt;/li&gt;
&lt;li&gt;every strategy has the correct signature&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Step 3: Type the main function
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PaymentMethod&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;paymentStrategies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nf"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No need for runtime checks anymore.&lt;/p&gt;

&lt;p&gt;Errors are caught at compile time.&lt;/p&gt;




&lt;h3&gt;
  
  
  Why this matters
&lt;/h3&gt;

&lt;p&gt;With JavaScript, you make your code flexible.&lt;br&gt;
With TypeScript, you make it reliable.&lt;/p&gt;

&lt;p&gt;You’re not just cleaning your code.&lt;/p&gt;

&lt;p&gt;You’re making invalid states impossible.&lt;/p&gt;


&lt;h2&gt;
  
  
  Optional: Class-Based Strategy
&lt;/h2&gt;

&lt;p&gt;If you prefer a more OOP-style approach with JavaScript, you can model strategies as classes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreditCardStrategy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Processing credit card payment:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PayPalStrategy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Processing PayPal payment:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use them like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;strategies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;credit-card&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CreditCardStrategy&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;paypal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PayPalStrategy&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;processPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;strategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;strategies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Unsupported payment method&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;strategy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s more structured, but also more verbose.&lt;/p&gt;

&lt;p&gt;In JavaScript, the functional approach is usually enough.&lt;/p&gt;




&lt;h2&gt;
  
  
  When to Use (and Not Use) Strategy
&lt;/h2&gt;

&lt;p&gt;Use it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you have multiple variants of the same behavior&lt;/li&gt;
&lt;li&gt;new cases are added frequently&lt;/li&gt;
&lt;li&gt;conditionals are growing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avoid it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you only have a couple of simple cases&lt;/li&gt;
&lt;li&gt;the logic is unlikely to change&lt;/li&gt;
&lt;li&gt;it adds unnecessary complexity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to apply patterns, but to &lt;strong&gt;solve real problems&lt;/strong&gt;.&lt;/p&gt;




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

&lt;p&gt;The Strategy Pattern isn’t about being clever, it’s about writing code that can grow without becoming fragile.&lt;/p&gt;

&lt;p&gt;Most messy &lt;code&gt;if-else&lt;/code&gt; chains don’t start messy, they become messy over time and by the time you notice, changing them feels risky.&lt;/p&gt;

&lt;p&gt;The good news is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You don’t need a rewrite, just a better way to organize behavior.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;If this helped you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leave a ❤️ reaction&lt;/li&gt;
&lt;li&gt;Drop a 🦄 unicorn&lt;/li&gt;
&lt;li&gt;Share the worst &lt;code&gt;if-else&lt;/code&gt; monster you’ve seen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you enjoy this kind of content, follow me here on DEV for more.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Code Reviews Without Drama: How Great Teams Give Feedback That Actually Helps</title>
      <dc:creator>Gavin Cettolo</dc:creator>
      <pubDate>Tue, 07 Apr 2026 07:30:00 +0000</pubDate>
      <link>https://dev.to/gavincettolo/code-reviews-without-drama-how-great-teams-give-feedback-that-actually-helps-3cd2</link>
      <guid>https://dev.to/gavincettolo/code-reviews-without-drama-how-great-teams-give-feedback-that-actually-helps-3cd2</guid>
      <description>&lt;p&gt;A few years ago, I left a code review feeling… weird.&lt;/p&gt;

&lt;p&gt;The code worked.&lt;/p&gt;

&lt;p&gt;Tests were passing.&lt;/p&gt;

&lt;p&gt;But the comments?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“This is wrong”&lt;/p&gt;

&lt;p&gt;“Bad approach”&lt;/p&gt;

&lt;p&gt;“Rewrite this”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;No explanation.&lt;/p&gt;

&lt;p&gt;No context.&lt;/p&gt;

&lt;p&gt;Just judgment.&lt;/p&gt;

&lt;p&gt;Nothing was technically incorrect.&lt;/p&gt;

&lt;p&gt;But something was off.&lt;/p&gt;

&lt;p&gt;That’s when it clicked:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Code reviews aren’t just about code, they’re about communication.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And done poorly, they don’t improve the codebase, they just slowly damage the team.&lt;/p&gt;




&lt;h4&gt;
  
  
  TL;DR
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Great code reviews focus on &lt;strong&gt;improving the code, not judging the developer&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The difference is in &lt;strong&gt;how feedback is framed&lt;/strong&gt;, not just what is said.&lt;/li&gt;
&lt;li&gt;Healthy teams optimize for &lt;strong&gt;clarity, context, and collaboration&lt;/strong&gt;, not ego.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ul&gt;
&lt;li&gt;Why Code Reviews Go Wrong&lt;/li&gt;
&lt;li&gt;What Great Code Reviews Actually Do&lt;/li&gt;
&lt;li&gt;1. Focus on the Code, Not the Person&lt;/li&gt;
&lt;li&gt;2. Explain the Why, Not Just the What&lt;/li&gt;
&lt;li&gt;3. Turn Judgments Into Questions&lt;/li&gt;
&lt;li&gt;4. Avoid Bike-Shedding&lt;/li&gt;
&lt;li&gt;5. Balance Speed and Depth&lt;/li&gt;
&lt;li&gt;Real Example: From Harsh to Helpful&lt;/li&gt;
&lt;li&gt;How to Handle Receiving Feedback&lt;/li&gt;
&lt;li&gt;Practical Team Agreements&lt;/li&gt;
&lt;li&gt;Final Thoughts&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why Code Reviews Go Wrong
&lt;/h2&gt;

&lt;p&gt;Most developers don’t &lt;em&gt;want&lt;/em&gt; to give bad feedback, but code reviews often become tense anyway.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because they sit at the intersection of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ownership (“this is my code”)&lt;/li&gt;
&lt;li&gt;identity (“this reflects my skills”)&lt;/li&gt;
&lt;li&gt;time pressure (“we need to ship”)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add a bit of unclear communication, and things escalate quickly.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What starts as feedback becomes criticism.&lt;br&gt;
What should be collaboration becomes friction.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What Great Code Reviews Actually Do
&lt;/h2&gt;

&lt;p&gt;A good code review doesn’t just catch bugs.&lt;/p&gt;

&lt;p&gt;It does three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;improves the code&lt;/li&gt;
&lt;li&gt;shares knowledge&lt;/li&gt;
&lt;li&gt;strengthens the team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If one of these is missing, something is off, especially the last one, because a team that avoids reviews or fears them will never move fast in the long run.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Focus on the Code, Not the Person
&lt;/h2&gt;

&lt;p&gt;This sounds obvious, but small wording differences matter a lot.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;This is wrong
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;vs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;This logic might lead to edge cases when the input is empty
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first feels like judgment.&lt;br&gt;
The second feels like collaboration.&lt;/p&gt;

&lt;p&gt;A simple shift helps:&lt;/p&gt;

&lt;p&gt;👉 describe the &lt;strong&gt;problem&lt;/strong&gt;, not the &lt;strong&gt;person&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“you did this wrong”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“this approach could cause issues because…”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s a small change, but it completely changes how feedback is received.&lt;/p&gt;


&lt;h2&gt;
  
  
  2. Explain the Why, Not Just the What
&lt;/h2&gt;

&lt;p&gt;One of the most frustrating things in code reviews is vague feedback.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Refactor this
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;What’s the problem?&lt;/p&gt;

&lt;p&gt;What’s the goal?&lt;/p&gt;

&lt;p&gt;Without context, the comment becomes noise.&lt;/p&gt;

&lt;p&gt;Good feedback always answers one question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why does this matter?&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;This works, but extracting this into a function could make it easier to test and reuse
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the author understands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the intent&lt;/li&gt;
&lt;li&gt;the benefit&lt;/li&gt;
&lt;li&gt;the trade-off&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And can make a better decision.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Turn Judgments Into Questions
&lt;/h2&gt;

&lt;p&gt;When in doubt, &lt;strong&gt;ask&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Questions are powerful because they:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;invite discussion&lt;/li&gt;
&lt;li&gt;reduce defensiveness&lt;/li&gt;
&lt;li&gt;uncover context you might be missing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;This is over-engineered
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Do we need this level of abstraction here, or could a simpler approach work?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same concern.&lt;/p&gt;

&lt;p&gt;Completely different outcome.&lt;/p&gt;

&lt;p&gt;Sometimes, you’ll even realize the original author had a valid reason.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Avoid Bike-Shedding
&lt;/h2&gt;

&lt;p&gt;Not all feedback has the same weight, but many reviews treat everything equally.&lt;/p&gt;

&lt;p&gt;You end up with long threads about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;variable names&lt;/li&gt;
&lt;li&gt;formatting&lt;/li&gt;
&lt;li&gt;personal preferences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While more important issues get less attention.&lt;/p&gt;

&lt;p&gt;This is called &lt;strong&gt;bike-shedding&lt;/strong&gt; and it kills productivity.&lt;/p&gt;

&lt;p&gt;A simple rule helps:&lt;/p&gt;

&lt;p&gt;👉 focus on what impacts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;correctness&lt;/li&gt;
&lt;li&gt;readability&lt;/li&gt;
&lt;li&gt;maintainability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Leave the rest to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;linters&lt;/li&gt;
&lt;li&gt;formatters&lt;/li&gt;
&lt;li&gt;team conventions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your energy is limited, so use it where it matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Balance Speed and Depth
&lt;/h2&gt;

&lt;p&gt;There’s a tension in every code review:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;go deep → better quality&lt;/li&gt;
&lt;li&gt;go fast → better velocity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Great teams don’t pick one, &lt;strong&gt;they balance both&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Some practical ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;keep PRs small&lt;/li&gt;
&lt;li&gt;review early, not just at the end&lt;/li&gt;
&lt;li&gt;avoid “mega reviews” with 1000+ lines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the larger the change, the harder it is to review well.&lt;/p&gt;

&lt;p&gt;And the easier it is for issues to slip through.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real Example: From Harsh to Helpful
&lt;/h2&gt;

&lt;p&gt;Let’s take a real-style example.&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Harsh
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;This is messy. Refactor it.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;confusion&lt;/li&gt;
&lt;li&gt;frustration&lt;/li&gt;
&lt;li&gt;back-and-forth&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ✅ Helpful
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;This works, but it’s a bit hard to follow due to the nested conditions.

What do you think about extracting this part into a separate function? It might make the flow easier to read and test.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;context&lt;/li&gt;
&lt;li&gt;suggestion&lt;/li&gt;
&lt;li&gt;collaboration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same intent, much better outcome.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Handle Receiving Feedback
&lt;/h2&gt;

&lt;p&gt;Giving feedback is only half of the equation.&lt;/p&gt;

&lt;p&gt;Receiving it matters just as much.&lt;/p&gt;

&lt;p&gt;A few things that help:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;assume positive intent&lt;/li&gt;
&lt;li&gt;ask for clarification if something is unclear&lt;/li&gt;
&lt;li&gt;don’t take comments personally&lt;/li&gt;
&lt;li&gt;push back when needed, but with context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good code review is not about agreeing on everything.&lt;/p&gt;

&lt;p&gt;It’s about reaching a better solution together.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Team Agreements
&lt;/h2&gt;

&lt;p&gt;The best teams don’t leave this to chance.&lt;/p&gt;

&lt;p&gt;They define how reviews should work.&lt;/p&gt;

&lt;p&gt;A few simple agreements can make a big difference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Explain the why” is mandatory&lt;/li&gt;
&lt;li&gt;Prefer questions over judgments&lt;/li&gt;
&lt;li&gt;Focus on high-impact issues first&lt;/li&gt;
&lt;li&gt;Keep PRs small and focused&lt;/li&gt;
&lt;li&gt;No ego in discussions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are small rules, but they create a much healthier environment.&lt;/p&gt;




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

&lt;p&gt;Code reviews are one of the most powerful tools a team has, but only if they’re done right because bad reviews don’t just slow down development, they create &lt;strong&gt;friction&lt;/strong&gt;, &lt;strong&gt;frustration&lt;/strong&gt;, and eventually &lt;strong&gt;silence&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Great reviews do the opposite:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They improve the code.&lt;/li&gt;
&lt;li&gt;They spread knowledge.&lt;/li&gt;
&lt;li&gt;They build trust.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And in the long run, that’s what makes a team truly fast.&lt;/p&gt;




&lt;p&gt;If this resonated with you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leave a ❤️ reaction&lt;/li&gt;
&lt;li&gt;Drop a 🦄 unicorn&lt;/li&gt;
&lt;li&gt;Share the best (or worst) code review you’ve experienced&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you enjoy this kind of content, follow me here on DEV for more.&lt;/p&gt;

</description>
      <category>career</category>
      <category>codereview</category>
      <category>softwareengineering</category>
      <category>programming</category>
    </item>
    <item>
      <title>Bad Code Is a High-Interest Loan: How Technical Debt Slowly Kills Team Velocity</title>
      <dc:creator>Gavin Cettolo</dc:creator>
      <pubDate>Tue, 31 Mar 2026 07:30:00 +0000</pubDate>
      <link>https://dev.to/gavincettolo/bad-code-is-a-high-interest-loan-how-technical-debt-slowly-kills-team-velocity-lac</link>
      <guid>https://dev.to/gavincettolo/bad-code-is-a-high-interest-loan-how-technical-debt-slowly-kills-team-velocity-lac</guid>
      <description>&lt;p&gt;We were moving fast.&lt;/p&gt;

&lt;p&gt;Features shipped every week.&lt;/p&gt;

&lt;p&gt;Stakeholders were happy.&lt;/p&gt;

&lt;p&gt;The backlog was finally under control.&lt;/p&gt;

&lt;p&gt;Then, almost without noticing, everything slowed down. A feature that should have taken a day took three abd a small change broke something unrelated. Fixing bugs started taking longer than building new features.&lt;br&gt;
And at some point, someone said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“But this used to be faster, right?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They weren’t wrong. At some point in the past, things &lt;em&gt;were&lt;/em&gt; faster, but that speed came at a cost.&lt;/p&gt;

&lt;p&gt;A cost that wasn’t visible at the time.&lt;br&gt;
A cost that quietly accumulated.&lt;/p&gt;

&lt;p&gt;This is something I’ve often wanted to explain to non-technical stakeholders:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;we didn’t suddenly become slower, we’re just paying back what we borrowed.&lt;/p&gt;
&lt;/blockquote&gt;


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

&lt;ul&gt;
&lt;li&gt;Technical debt behaves like a &lt;strong&gt;high-interest loan&lt;/strong&gt;: it feels cheap at first, but becomes expensive over time.&lt;/li&gt;
&lt;li&gt;The real problem isn’t having technical debt, it’s &lt;strong&gt;letting it compound unmanaged&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Refactoring isn’t a cost, it’s an &lt;strong&gt;investment with measurable ROI&lt;/strong&gt; in team velocity.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;ul&gt;
&lt;li&gt;The Illusion of Speed&lt;/li&gt;
&lt;li&gt;Technical Debt as a Financial Model&lt;/li&gt;
&lt;li&gt;Where the Interest Shows Up&lt;/li&gt;
&lt;li&gt;The Compounding Effect&lt;/li&gt;
&lt;li&gt;When Teams Hit Default&lt;/li&gt;
&lt;li&gt;The ROI of Refactoring&lt;/li&gt;
&lt;li&gt;When NOT to Refactor&lt;/li&gt;
&lt;li&gt;Practical Ways to Manage Technical Debt&lt;/li&gt;
&lt;li&gt;Final Thoughts&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  The Illusion of Speed
&lt;/h2&gt;

&lt;p&gt;Technical debt often starts as a conscious trade-off:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You skip a refactor.&lt;/li&gt;
&lt;li&gt;You duplicate a bit of logic.&lt;/li&gt;
&lt;li&gt;You hardcode something “just for now”.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And in the moment, it feels like the right decision because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You move faster.&lt;/li&gt;
&lt;li&gt;You deliver sooner.&lt;/li&gt;
&lt;li&gt;You hit the deadline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s why it’s so hard to avoid, because it &lt;em&gt;works&lt;/em&gt;, but what you’re really doing is borrowing time from your future self and like any loan, &lt;strong&gt;that time comes back&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Technical Debt as a Financial Model
&lt;/h2&gt;

&lt;p&gt;One of the most useful ways to think about technical debt is to treat it like an actual financial system.&lt;br&gt;
Not just a metaphor, but a model.&lt;/p&gt;
&lt;h3&gt;
  
  
  Principal: the shortcut
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;principal&lt;/strong&gt; is the initial shortcut you take:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;skipping a proper abstraction&lt;/li&gt;
&lt;li&gt;duplicating logic instead of extracting it&lt;/li&gt;
&lt;li&gt;shipping a workaround instead of fixing the root cause&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Individually, these decisions are often reasonable.&lt;/p&gt;

&lt;p&gt;Sometimes even necessary.&lt;/p&gt;


&lt;h3&gt;
  
  
  Interest: the friction
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;interest&lt;/strong&gt; is what you pay every time you touch that code again. It shows up as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;extra time to understand what’s happening&lt;/li&gt;
&lt;li&gt;unexpected side effects&lt;/li&gt;
&lt;li&gt;more effort to implement even simple changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don’t notice it immediately.&lt;/p&gt;

&lt;p&gt;But it’s there, every time.&lt;/p&gt;


&lt;h3&gt;
  
  
  Compounding: the multiplier
&lt;/h3&gt;

&lt;p&gt;And then comes the real problem: &lt;strong&gt;compounding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each new feature built on top of messy code increases the cost of the next one.&lt;/p&gt;

&lt;p&gt;Not linearly.&lt;/p&gt;

&lt;p&gt;Exponentially.&lt;/p&gt;


&lt;h2&gt;
  
  
  Where the Interest Shows Up
&lt;/h2&gt;

&lt;p&gt;Interest doesn’t arrive as a big, visible cost, it shows up as friction.&lt;/p&gt;

&lt;p&gt;Small things that make your work just a bit slower, every single day.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A feature takes longer than expected&lt;/li&gt;
&lt;li&gt;A bug fix introduces another bug&lt;/li&gt;
&lt;li&gt;You spend more time reading code than writing it&lt;/li&gt;
&lt;li&gt;Onboarding a new developer becomes difficult&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Or even something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// "temporary" workaround from 6 months ago&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;role&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;featureFlagX&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// special case inside special case&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing here breaks the system, but everything here slows you down.&lt;/p&gt;

&lt;p&gt;That’s the &lt;strong&gt;interest&lt;/strong&gt; you’re paying.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Compounding Effect
&lt;/h2&gt;

&lt;p&gt;This is where things become dangerous.&lt;/p&gt;

&lt;p&gt;Technical debt doesn’t just add cost, it multiplies it. Every new feature built on top of unclear or fragile code becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;harder to implement&lt;/li&gt;
&lt;li&gt;harder to test&lt;/li&gt;
&lt;li&gt;harder to change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the next feature takes longer.&lt;/p&gt;

&lt;p&gt;And the next one.&lt;/p&gt;

&lt;p&gt;And the next one.&lt;/p&gt;

&lt;p&gt;At some point, the system isn’t just complex.&lt;/p&gt;

&lt;p&gt;It’s actively resisting change.&lt;/p&gt;

&lt;p&gt;And that’s when velocity starts dropping, even if your team hasn’t changed at all.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Teams Hit Default
&lt;/h2&gt;

&lt;p&gt;In finance, default happens when you can’t repay your debt anymore.&lt;/p&gt;

&lt;p&gt;In software, it looks different, but the signal is clear.&lt;/p&gt;

&lt;p&gt;You see it when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;refactoring is always postponed&lt;/li&gt;
&lt;li&gt;certain parts of the codebase are avoided&lt;/li&gt;
&lt;li&gt;every release feels risky&lt;/li&gt;
&lt;li&gt;progress slows down despite increasing effort&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this stage, teams often react the wrong way.&lt;/p&gt;

&lt;p&gt;They try to push harder.&lt;/p&gt;

&lt;p&gt;More hours.&lt;/p&gt;

&lt;p&gt;More pressure.&lt;/p&gt;

&lt;p&gt;More “just ship it”.&lt;/p&gt;

&lt;p&gt;But the problem isn’t effort.&lt;/p&gt;

&lt;p&gt;It’s accumulated complexity.&lt;/p&gt;

&lt;p&gt;And no amount of speed can compensate for that.&lt;/p&gt;




&lt;h2&gt;
  
  
  The ROI of Refactoring
&lt;/h2&gt;

&lt;p&gt;Refactoring is often perceived as a cost, something that slows down delivery, something you “don’t have time for”, but that perspective ignores the return.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Refactoring is an investment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And like any investment, it pays off over time.&lt;/p&gt;

&lt;p&gt;Let’s make it concrete, imagine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A feature currently takes &lt;strong&gt;3 days&lt;/strong&gt; to implement&lt;/li&gt;
&lt;li&gt;After refactoring, similar features take &lt;strong&gt;1.5 days&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s a 50% improvement.&lt;br&gt;
Over 10 features, you’ve saved 15 days.&lt;br&gt;
That’s not just cleaner code, that’s &lt;strong&gt;recovered velocity&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And just like debt compounds negatively, good code compounds positively:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;faster development&lt;/li&gt;
&lt;li&gt;fewer bugs&lt;/li&gt;
&lt;li&gt;easier onboarding&lt;/li&gt;
&lt;li&gt;more confidence in changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where engineering meets business, because velocity is not just a technical metric, it’s a &lt;strong&gt;business advantage&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  When NOT to Refactor
&lt;/h2&gt;

&lt;p&gt;Not all debt needs to be repaid immediately, and not all code needs to be perfect.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Refactoring everything blindly can be just as harmful.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Avoid refactoring when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the code is rarely touched&lt;/li&gt;
&lt;li&gt;the feature is about to be replaced&lt;/li&gt;
&lt;li&gt;you’re still validating a product idea&lt;/li&gt;
&lt;li&gt;the cost clearly outweighs the benefit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to eliminate technical debt, but it’s to &lt;strong&gt;manage it intentionally&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Ways to Manage Technical Debt
&lt;/h2&gt;

&lt;p&gt;You don’t need a full rewrite to stay in control, you need consistency.&lt;/p&gt;

&lt;p&gt;A few habits make a huge difference over time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Refactor as you go&lt;/strong&gt;: improve code while you’re already working on it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Make debt visible&lt;/strong&gt;: track it instead of hiding it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set a refactoring budget&lt;/strong&gt;: even 10–20% of time is enough&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review for maintainability&lt;/strong&gt;, not just correctness&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Call out complexity early&lt;/strong&gt;, before it spreads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are small actions, but they prevent large problems.&lt;/p&gt;




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

&lt;p&gt;Technical debt isn’t the enemy, it’s a tool.&lt;/p&gt;

&lt;p&gt;Sometimes you take on debt to move faster and that’s a valid decision, but if you ignore it, it becomes a liability and, eventually, it starts slowing everything down.&lt;/p&gt;

&lt;p&gt;The real problem isn’t having technical debt.&lt;/p&gt;

&lt;p&gt;It’s pretending you don’t.&lt;/p&gt;




&lt;p&gt;If this resonated with you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leave a ❤️ reaction&lt;/li&gt;
&lt;li&gt;Drop a 🦄 unicorn&lt;/li&gt;
&lt;li&gt;Share the most “expensive” piece of bad code you’ve seen&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you enjoy this kind of content, follow me here on DEV for more.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
      <category>discuss</category>
    </item>
    <item>
      <title>React Components vs Spaghetti: 5 Signs Your UI Is Becoming Unmaintainable</title>
      <dc:creator>Gavin Cettolo</dc:creator>
      <pubDate>Tue, 24 Mar 2026 08:30:00 +0000</pubDate>
      <link>https://dev.to/gavincettolo/react-components-vs-spaghetti-5-signs-your-ui-is-becoming-unmaintainable-120m</link>
      <guid>https://dev.to/gavincettolo/react-components-vs-spaghetti-5-signs-your-ui-is-becoming-unmaintainable-120m</guid>
      <description>&lt;p&gt;Last week I opened a React component… and immediately closed it.&lt;/p&gt;

&lt;p&gt;Not because it was complex.&lt;/p&gt;

&lt;p&gt;But because it felt &lt;em&gt;hostile&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You know that feeling: the file keeps scrolling, props are flying around, and every small change feels like it might break something completely unrelated.&lt;/p&gt;

&lt;p&gt;That’s not complexity.&lt;/p&gt;

&lt;p&gt;That’s entropy.&lt;/p&gt;

&lt;p&gt;And if you’ve been building UIs for a while, you’ve probably seen it happen slowly, almost invisibly.&lt;/p&gt;

&lt;p&gt;Let’s talk about the signals before things get out of hand.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;If your React components start feeling &lt;strong&gt;hard to read, fragile, or unpredictable&lt;/strong&gt;, your UI is likely becoming unmaintainable.&lt;/li&gt;
&lt;li&gt;The most common signals are &lt;strong&gt;oversized components, props drilling, unclear responsibilities, duplication, and messy conditionals&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You don’t need a rewrite, just &lt;strong&gt;small, consistent refactoring habits&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




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

&lt;ul&gt;
&lt;li&gt;The Problem with “It Still Works”&lt;/li&gt;
&lt;li&gt;1. The God Component (Too Big to Understand)&lt;/li&gt;
&lt;li&gt;2. Props Drilling Everywhere&lt;/li&gt;
&lt;li&gt;3. Confusing Responsibilities&lt;/li&gt;
&lt;li&gt;4. UI Logic Duplication&lt;/li&gt;
&lt;li&gt;5. Conditional Rendering Hell&lt;/li&gt;
&lt;li&gt;Bonus Signs You Shouldn’t Ignore&lt;/li&gt;
&lt;li&gt;Mini Refactoring: From Spaghetti to Clean&lt;/li&gt;
&lt;li&gt;Practical Refactoring Rituals&lt;/li&gt;
&lt;li&gt;Final Thoughts&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Problem with “It Still Works”
&lt;/h2&gt;

&lt;p&gt;Most messy UIs don’t start messy.&lt;/p&gt;

&lt;p&gt;They start small, clear, even elegant.&lt;/p&gt;

&lt;p&gt;Then a feature gets added.&lt;/p&gt;

&lt;p&gt;Then another one.&lt;/p&gt;

&lt;p&gt;Then a quick fix before a deadline.&lt;/p&gt;

&lt;p&gt;Nothing dramatic, just small decisions that make sense in the moment.&lt;/p&gt;

&lt;p&gt;Until one day you open a file and realize you don’t really &lt;em&gt;understand it anymore&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That’s the moment where “it still works” becomes dangerous.&lt;/p&gt;

&lt;p&gt;Because now every change carries risk.&lt;/p&gt;

&lt;p&gt;And the cost of touching the code becomes higher than leaving it alone.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The God Component (Too Big to Understand)
&lt;/h2&gt;

&lt;p&gt;There’s usually one file in every project that everyone avoids.&lt;/p&gt;

&lt;p&gt;It’s big. Really big.&lt;/p&gt;

&lt;p&gt;It handles data, UI, state, events, and probably a few side effects too.&lt;/p&gt;

&lt;p&gt;Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Dashboard&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// fetching logic&lt;/span&gt;
  &lt;span class="c1"&gt;// filtering logic&lt;/span&gt;
  &lt;span class="c1"&gt;// UI rendering&lt;/span&gt;
  &lt;span class="c1"&gt;// event handlers&lt;/span&gt;
  &lt;span class="c1"&gt;// conditionals everywhere&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* hundreds of lines */&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The issue isn’t just the size.&lt;/p&gt;

&lt;p&gt;It’s the lack of boundaries.&lt;/p&gt;

&lt;p&gt;When everything lives in the same place, nothing is clearly defined.&lt;/p&gt;

&lt;p&gt;You don’t know what’s safe to change and what might break something else.&lt;/p&gt;

&lt;p&gt;A useful rule I rely on is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you can’t describe a component in one sentence, it’s doing too much.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Breaking it down doesn’t mean over-engineering.&lt;/p&gt;

&lt;p&gt;It means restoring clarity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Dashboard&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserHeader&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PostList&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now each piece has a purpose.&lt;/p&gt;

&lt;p&gt;And more importantly, a limit.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Props Drilling Everywhere
&lt;/h2&gt;

&lt;p&gt;Props drilling usually starts innocently.&lt;/p&gt;

&lt;p&gt;You pass &lt;code&gt;user&lt;/code&gt; from a parent to a child, then to another child, then another.&lt;/p&gt;

&lt;p&gt;Until you end up here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dashboard&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserAvatar&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Sidebar&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Dashboard&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, some components are just acting as pipelines.&lt;/p&gt;

&lt;p&gt;They don’t use the data, they just pass it along.&lt;/p&gt;

&lt;p&gt;That creates a subtle kind of friction.&lt;/p&gt;

&lt;p&gt;Every layer becomes aware of something it doesn’t actually care about.&lt;/p&gt;

&lt;p&gt;And any change to that data ripples through the entire tree.&lt;/p&gt;

&lt;p&gt;The obvious solution is often:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Let’s use Context.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that’s valid… but only to a point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context is not a silver bullet.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Overusing it can make your app harder to reason about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data becomes less explicit&lt;/li&gt;
&lt;li&gt;re-renders become harder to control&lt;/li&gt;
&lt;li&gt;tracing where values come from gets tricky&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A better approach is to use it &lt;strong&gt;intentionally&lt;/strong&gt;, when it actually solves a real problem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;truly global data (auth, theme, user)&lt;/li&gt;
&lt;li&gt;deeply shared state&lt;/li&gt;
&lt;li&gt;repeated props drilling across many levels&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Combined with a custom hook, it stays clean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;useContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;UserContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;UserAvatar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;img&lt;/span&gt; &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;avatar&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the dependency lives exactly where it’s needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Confusing Responsibilities
&lt;/h2&gt;

&lt;p&gt;Sometimes the problem isn’t visible at a glance.&lt;/p&gt;

&lt;p&gt;It’s not about how much code there is, but about &lt;em&gt;what kind&lt;/em&gt; of work is happening in the same place.&lt;/p&gt;

&lt;p&gt;A single component handling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data fetching&lt;/li&gt;
&lt;li&gt;state management&lt;/li&gt;
&lt;li&gt;transformation&lt;/li&gt;
&lt;li&gt;rendering&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…is doing too many different jobs.&lt;/p&gt;

&lt;p&gt;The result is cognitive overload.&lt;/p&gt;

&lt;p&gt;You open the file and constantly switch context:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Am I reading UI? Or logic? Or data?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That friction slows everything down.&lt;/p&gt;

&lt;p&gt;Separating responsibilities makes the code easier to navigate and easier to trust.&lt;/p&gt;

&lt;p&gt;A simple split already helps a lot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;usePosts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// fetch + transform&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PostList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;usePosts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the component reads like a story again, not a puzzle.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. UI Logic Duplication
&lt;/h2&gt;

&lt;p&gt;Duplication doesn’t always look like copy-paste.&lt;/p&gt;

&lt;p&gt;Sometimes it shows up as repeated patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Spinner&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You write it once.&lt;/p&gt;

&lt;p&gt;Then again.&lt;/p&gt;

&lt;p&gt;Then again.&lt;/p&gt;

&lt;p&gt;At some point, changing that behavior means updating multiple places.&lt;/p&gt;

&lt;p&gt;That’s when it becomes expensive.&lt;/p&gt;

&lt;p&gt;Extracting shared logic is less about abstraction and more about &lt;strong&gt;centralizing decisions&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;DataState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Spinner&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the behavior lives in one place.&lt;/p&gt;

&lt;p&gt;And your UI becomes more consistent by default.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Conditional Rendering Hell
&lt;/h2&gt;

&lt;p&gt;Conditional rendering is fine.&lt;/p&gt;

&lt;p&gt;Until it isn’t.&lt;/p&gt;

&lt;p&gt;We’ve all written something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;isAdmin&lt;/span&gt;
  &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;isActive&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AdminPanel&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;InactiveAdmin&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserPanel&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works.&lt;/p&gt;

&lt;p&gt;But it’s not easy to read.&lt;/p&gt;

&lt;p&gt;The problem isn’t React.&lt;/p&gt;

&lt;p&gt;It’s that too much logic is living inside JSX.&lt;/p&gt;

&lt;p&gt;A first step is to move that logic out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;renderContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isAdmin&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AdminPanel&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isAdmin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;InactiveAdmin&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserPanel&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;renderContent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Already much better.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Guard Clauses
&lt;/h3&gt;

&lt;p&gt;Guard clauses can make this even clearer, when used carefully.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isAdmin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserPanel&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;InactiveAdmin&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AdminPanel&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This removes nesting and keeps the flow linear.&lt;/p&gt;

&lt;p&gt;The key is balance.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;use guard clauses when they simplify the flow&lt;/li&gt;
&lt;li&gt;avoid stacking too many negative conditions&lt;/li&gt;
&lt;li&gt;keep the logic readable from top to bottom&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal isn’t fewer lines.&lt;/p&gt;

&lt;p&gt;It’s clarity.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus Signs You Shouldn’t Ignore
&lt;/h2&gt;

&lt;p&gt;Sometimes the signals are less technical and more instinctive.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You hesitate before opening a file&lt;/li&gt;
&lt;li&gt;You’re afraid to change something&lt;/li&gt;
&lt;li&gt;Fixing a bug feels risky&lt;/li&gt;
&lt;li&gt;You’ve said “let’s not touch this” more than once&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are all valid warnings.&lt;/p&gt;

&lt;p&gt;And they usually show up before bigger problems.&lt;/p&gt;




&lt;h2&gt;
  
  
  Mini Refactoring: From Spaghetti to Clean
&lt;/h2&gt;

&lt;p&gt;A while ago I ran into a component like this.&lt;/p&gt;

&lt;p&gt;It wasn’t broken.&lt;/p&gt;

&lt;p&gt;It wasn’t even that complex.&lt;/p&gt;

&lt;p&gt;But it had that feeling:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“There’s just a bit too much going on here.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  ❌ Before
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Dashboard&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFilter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filteredPosts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;select&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setFilter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"all"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;All&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"tech"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tech&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;select&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;filteredPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;No posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;filteredPosts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing wrong, technically.&lt;/p&gt;

&lt;p&gt;But everything is mixed together:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;state&lt;/li&gt;
&lt;li&gt;logic&lt;/li&gt;
&lt;li&gt;UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I started small.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 1: isolate the logic
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useFilteredPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFilter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filtered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;filter&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;all&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFilter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filtered&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the component doesn’t care &lt;em&gt;how&lt;/em&gt; filtering works.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 2: extract reusable UI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;PostFilter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onChange&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;select&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"all"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;All&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"tech"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Tech&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;option&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;select&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 3: compose everything
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Dashboard&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;Props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setFilter&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filtered&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useFilteredPosts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;PostFilter&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setFilter&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;No posts&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;filtered&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same feature.&lt;/p&gt;

&lt;p&gt;Completely different feeling.&lt;/p&gt;

&lt;p&gt;That’s the real goal of refactoring.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Refactoring Rituals
&lt;/h2&gt;

&lt;p&gt;You don’t need a full rewrite to fix spaghetti code.&lt;/p&gt;

&lt;p&gt;You need habits.&lt;/p&gt;

&lt;p&gt;Refactoring works best when it’s part of your workflow, not something you postpone.&lt;/p&gt;

&lt;p&gt;A few simple ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;extract things early, when they start feeling “off”&lt;/li&gt;
&lt;li&gt;keep components focused on one responsibility&lt;/li&gt;
&lt;li&gt;move growing logic into hooks&lt;/li&gt;
&lt;li&gt;spend time naming things clearly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these are revolutionary.&lt;/p&gt;

&lt;p&gt;But together, they make your codebase easier to work with.&lt;/p&gt;




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

&lt;p&gt;Spaghetti UI isn’t a failure.&lt;/p&gt;

&lt;p&gt;It’s what happens when real features meet real constraints.&lt;/p&gt;

&lt;p&gt;But if you ignore it, it slowly turns your codebase into something you avoid instead of something you trust.&lt;/p&gt;

&lt;p&gt;The good news is, you don’t need perfection.&lt;/p&gt;

&lt;p&gt;Just small improvements, applied consistently.&lt;/p&gt;




&lt;p&gt;If this article resonated with you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leave a ❤️ reaction&lt;/li&gt;
&lt;li&gt;Drop a 🦄 unicorn&lt;/li&gt;
&lt;li&gt;Share the worst component you’ve ever written (or seen) in the comments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you enjoy this kind of content, follow me here on DEV for more.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>javascript</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Next.js Folder Zen: Padroneggiare la Directory app/</title>
      <dc:creator>Gavin Cettolo</dc:creator>
      <pubDate>Wed, 18 Mar 2026 08:30:00 +0000</pubDate>
      <link>https://dev.to/gavincettolo/nextjs-folder-zen-padroneggiare-la-directory-app-485k</link>
      <guid>https://dev.to/gavincettolo/nextjs-folder-zen-padroneggiare-la-directory-app-485k</guid>
      <description>&lt;p&gt;Se hai iniziato da poco a usare Next.js 13+, probabilmente hai aperto un progetto e hai pensato:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Perché questa struttura di cartelle sembra così... diversa?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Con l’&lt;strong&gt;App Router&lt;/strong&gt;, la directory &lt;code&gt;app/&lt;/code&gt; è diventata il cuore di ogni progetto Next.js moderno. Ma per molti sviluppatori—soprattutto quelli che arrivano dal vecchio &lt;code&gt;pages/&lt;/code&gt; router—la struttura delle cartelle può risultare inizialmente confusa.&lt;/p&gt;

&lt;p&gt;Sistemiamo le cose.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;La directory &lt;strong&gt;&lt;code&gt;app/&lt;/code&gt; di Next.js&lt;/strong&gt; introduce un’architettura basata su file che controlla routing, layout e comportamento del rendering.&lt;/li&gt;
&lt;li&gt;File speciali come &lt;strong&gt;&lt;code&gt;page.tsx&lt;/code&gt;, &lt;code&gt;layout.tsx&lt;/code&gt;, &lt;code&gt;loading.tsx&lt;/code&gt;, &lt;code&gt;error.tsx&lt;/code&gt; e &lt;code&gt;not-found.tsx&lt;/code&gt;&lt;/strong&gt; definiscono come si comportano le route.&lt;/li&gt;
&lt;li&gt;Una &lt;strong&gt;struttura pulita con route groups e dynamic routes&lt;/strong&gt; rende le app Next.js scalabili e manutenibili.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




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

&lt;ul&gt;
&lt;li&gt;Perché la directory app/ è importante&lt;/li&gt;
&lt;li&gt;Il concetto base: File-Based Routing&lt;/li&gt;
&lt;li&gt;I file essenziali dentro app/&lt;/li&gt;
&lt;li&gt;Layouts: l’arma segreta&lt;/li&gt;
&lt;li&gt;Loading ed Error States&lt;/li&gt;
&lt;li&gt;Error Boundaries: una limitazione importante&lt;/li&gt;
&lt;li&gt;Gestire le 404 con not-found.tsx&lt;/li&gt;
&lt;li&gt;Dynamic Routes&lt;/li&gt;
&lt;li&gt;Route Groups&lt;/li&gt;
&lt;li&gt;Una struttura reale&lt;/li&gt;
&lt;li&gt;Errori comuni&lt;/li&gt;
&lt;li&gt;Considerazioni finali&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Perché la directory &lt;code&gt;app/&lt;/code&gt; è importante
&lt;/h2&gt;

&lt;p&gt;Quando Next.js ha introdotto l’App Router, non era solo una nuova cartella.&lt;/p&gt;

&lt;p&gt;Era un cambio di paradigma.&lt;/p&gt;

&lt;p&gt;Invece di spargere la logica in più livelli, la directory &lt;code&gt;app/&lt;/code&gt; organizza l’app attorno a &lt;strong&gt;route e segmenti UI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Pensala così:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;URL → Cartella → UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Questo approccio rende le applicazioni grandi molto più facili da capire.&lt;/p&gt;

&lt;p&gt;Invece di chiederti:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Dov’è il componente per questa pagina?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vai direttamente nella cartella che corrisponde alla route.&lt;/p&gt;




&lt;h2&gt;
  
  
  Il concetto base: File-Based Routing
&lt;/h2&gt;

&lt;p&gt;Nel &lt;code&gt;app/&lt;/code&gt; directory il routing è semplice.&lt;/p&gt;

&lt;p&gt;Le cartelle definiscono le route.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  page.tsx
  about/
    page.tsx
  dashboard/
    page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Questo genera:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/           → page.tsx
/about      → about/page.tsx
/dashboard  → dashboard/page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Una pagina base:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello Next.js&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Zero configurazione di routing.&lt;/p&gt;




&lt;h2&gt;
  
  
  I file essenziali dentro &lt;code&gt;app/&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Next.js usa &lt;strong&gt;nomi di file speciali&lt;/strong&gt; per definire il comportamento.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;page.tsx&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Definisce la UI della route.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Dashboard&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ogni route accessibile deve avere un &lt;code&gt;page.tsx&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;layout.tsx&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;I layout wrappano più pagine e &lt;strong&gt;persistono durante la navigazione&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  layout.tsx
  dashboard/
    layout.tsx
    page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Navigation&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I layout non vengono ri-renderizzati durante la navigazione, il che li rende perfetti per:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;navbar&lt;/li&gt;
&lt;li&gt;sidebar&lt;/li&gt;
&lt;li&gt;UI condivisa&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Layouts: l’arma segreta
&lt;/h2&gt;

&lt;p&gt;Uno dei punti più forti dell’App Router sono i &lt;strong&gt;layout annidati&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  layout.tsx
  dashboard/
    layout.tsx
    analytics/
      page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Root Layout
   ↓
Dashboard Layout
   ↓
Analytics Page
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Questo permette UI complesse senza duplicare codice.&lt;/p&gt;




&lt;h2&gt;
  
  
  Loading ed Error States
&lt;/h2&gt;

&lt;p&gt;Next.js supporta stati UI a &lt;strong&gt;livello di route&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;loading.tsx&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Mostrato durante il caricamento.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Loading&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  &lt;code&gt;error.tsx&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Gestisce errori nel segmento.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// Gli error boundaries devono essere componenti client&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Something went wrong&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Error Boundaries: una limitazione importante
&lt;/h2&gt;

&lt;p&gt;Il file error.tsx funziona come un gestore di errori React per un segmento di percorso.&lt;/p&gt;

&lt;p&gt;Tuttavia, esiste un limite importante che molti sviluppatori trascurano.&lt;/p&gt;

&lt;p&gt;I gestori di errori non intercettano gli errori all'interno dei gestori di eventi.&lt;/p&gt;

&lt;p&gt;Cattura solo errori durante:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rendering&lt;/li&gt;
&lt;li&gt;server components&lt;/li&gt;
&lt;li&gt;data fetching&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;Error&lt;/span&gt;
  &lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;C'è stato un errore.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Riprova
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gli errori generati all'interno dei gestori di eventi devono comunque essere gestiti manualmente. Ad esempio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Boom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Considera error.tsx come una &lt;strong&gt;rete di sicurezza&lt;/strong&gt; per l'interfaccia utente, non come un sistema completo di gestione degli errori.&lt;/p&gt;




&lt;h2&gt;
  
  
  Gestire le 404 con &lt;code&gt;not-found.tsx&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Next.js semplifica le 404.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Pagina non trovata&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;notFound&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/navigation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;notFound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Supporta livelli multipli:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  not-found.tsx
  dashboard/
    not-found.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Viene usato quello più vicino.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dynamic Routes
&lt;/h2&gt;

&lt;p&gt;I dynamic routes usano le &lt;strong&gt;parentesi quadre&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ad esempio:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  blog/
    [slug]/
      page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;URL generati:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/blog/my-first-post
/blog/nextjs-routing
/blog/react-performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esempio di implementazione:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;BlogPost&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;params&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;È possibile combinarlo anche con la &lt;strong&gt;generazione statica&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Segmenti multipli
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  shop/
    [category]/
      [product]/
        page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esempi di route generate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/shop/laptops/macbook-pro
/shop/phones/iphone-15
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esempio di codice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ProductPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;params&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;
    &lt;span class="na"&gt;product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Category: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Route Catch-all
&lt;/h3&gt;

&lt;p&gt;A volte servono percorsi flessibili.&lt;/p&gt;

&lt;p&gt;Next.js supporta i &lt;strong&gt;segmenti catch-all&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[...slug]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  docs/
    [...slug]/
      page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;URL supportati:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/docs
/docs/getting-started
/docs/guides/routing
/docs/api/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;DocsPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;params&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Optional route catch-all
&lt;/h3&gt;

&lt;p&gt;È la versione opzionale:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[[...slug]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Questo supporta entrambi:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/docs
/docs/routing
/docs/config/api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tutto gestito dalla stessa pagina.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comprendere i Route Groups
&lt;/h2&gt;

&lt;p&gt;I Route Groups aiutano a organizzare il codice &lt;strong&gt;senza influire sugli URL&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Usano le parentesi tonde:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  (marketing)/
    page.tsx
    about/
      page.tsx

  (dashboard)/
    dashboard/
      page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;URL generati:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/
/about
/dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Non appaiono nelle URL e sono perfetti per separare diverse sezioni dell'app così da avere:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;layout differenti&lt;/li&gt;
&lt;li&gt;provider differenti&lt;/li&gt;
&lt;li&gt;strutture UI differenti&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Un esempio pratico
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  layout.tsx
  page.tsx

  (marketing)/
    page.tsx
    about/
      page.tsx

  (dashboard)/
    dashboard/
      layout.tsx
      page.tsx
      analytics/
        page.tsx
      settings/
        page.tsx

  blog/
    page.tsx
    [slug]/
      page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In questo modo, le &lt;strong&gt;pagine di marketing&lt;/strong&gt;, l'&lt;strong&gt;interfaccia utente dell'applicazione&lt;/strong&gt; e i &lt;strong&gt;percorsi dei contenuti&lt;/strong&gt; rimangono chiaramente separati.&lt;/p&gt;




&lt;h2&gt;
  
  
  Errori comuni
&lt;/h2&gt;

&lt;p&gt;Quando affianco sviluppatori che utilizzano Next.js, questi sono i problemi che riscontro più frequentemente.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Mischiare &lt;code&gt;pages/&lt;/code&gt; e &lt;code&gt;app/&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Sebbene tecnicamente possibile, crea confusione.&lt;/p&gt;

&lt;p&gt;Se inizi con &lt;code&gt;app/&lt;/code&gt;, &lt;strong&gt;mantieni solo app&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Cartelle annidate
&lt;/h3&gt;

&lt;p&gt;Mantieni la struttura semplice.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dashboard/analytics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Piuttosto che:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dashboard/features/analytics/pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. Ignorare i layout
&lt;/h3&gt;

&lt;p&gt;I layout sono una delle &lt;strong&gt;funzionalità più potenti&lt;/strong&gt; di App Router.&lt;/p&gt;

&lt;p&gt;Usateli.&lt;/p&gt;

&lt;p&gt;Semplificano notevolmente l'architettura.&lt;/p&gt;




&lt;h2&gt;
  
  
  Considerazioni finali
&lt;/h2&gt;

&lt;p&gt;La directory &lt;code&gt;app/&lt;/code&gt; potrebbe inizialmente sembrare insolita.&lt;/p&gt;

&lt;p&gt;Ma una volta che ci si prende la mano, diventa &lt;strong&gt;uno dei modi più puliti per strutturare le applicazioni React&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Invece di dover lottare con la configurazione del routing, i wrapper globali e la duplicazione dei layout, si ottiene un'architettura &lt;strong&gt;chiara e prevedibile&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Le cartelle rappresentano i percorsi&lt;/li&gt;
&lt;li&gt;File speciali controllano il comportamento&lt;/li&gt;
&lt;li&gt;I layout gestiscono l'interfaccia utente condivisa&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E improvvisamente il tuo progetto sembra molto più... &lt;strong&gt;zen&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;Se questo articolo ti è stato utile:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lascia un &lt;strong&gt;❤️&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;aggiungi un &lt;strong&gt;🦄&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;raccontami nei commenti come organizzi i tuoi progetti&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E se apprezzate contenuti di questo tipo, non esitate a &lt;strong&gt;seguirmi qui su DEV&lt;/strong&gt; per altri post su &lt;strong&gt;Next.js, architettura e produttività degli sviluppatori&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;EDIT: Questa è una versione riadattata in italiano di questo mio precedente articolo: &lt;a href="https://dev.to/gavincettolo/nextjs-folder-zen-mastering-the-app-directory-16go"&gt;Next.js Folder Zen: Mastering the app/ Directory&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>nextjs</category>
      <category>react</category>
    </item>
    <item>
      <title>Next.js Folder Zen: Mastering the app/ Directory</title>
      <dc:creator>Gavin Cettolo</dc:creator>
      <pubDate>Tue, 17 Mar 2026 08:30:00 +0000</pubDate>
      <link>https://dev.to/gavincettolo/nextjs-folder-zen-mastering-the-app-directory-16go</link>
      <guid>https://dev.to/gavincettolo/nextjs-folder-zen-mastering-the-app-directory-16go</guid>
      <description>&lt;p&gt;If you’ve recently started using &lt;strong&gt;Next.js 13+&lt;/strong&gt;, you’ve probably opened a project and thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Why does this folder structure feel so… different?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With the &lt;strong&gt;App Router&lt;/strong&gt;, the &lt;code&gt;app/&lt;/code&gt; directory became the heart of every modern Next.js project. But for many developers, especially those coming from the old &lt;code&gt;pages/&lt;/code&gt; router, the folder structure can feel confusing at first.&lt;/p&gt;

&lt;p&gt;Let’s fix that.&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;&lt;code&gt;app/&lt;/code&gt; directory in Next.js&lt;/strong&gt; introduces a file-system-based architecture that controls routing, layouts, and rendering behavior.&lt;/li&gt;
&lt;li&gt;Special files like &lt;strong&gt;&lt;code&gt;page.tsx&lt;/code&gt;, &lt;code&gt;layout.tsx&lt;/code&gt;, &lt;code&gt;loading.tsx&lt;/code&gt;, &lt;code&gt;error.tsx&lt;/code&gt;, and &lt;code&gt;not-found.tsx&lt;/code&gt;&lt;/strong&gt; define how routes behave.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;clean folder strategy with route groups and dynamic routes&lt;/strong&gt; makes large Next.js apps scalable and maintainable.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




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

&lt;ul&gt;
&lt;li&gt;Why the app/ Directory Matters&lt;/li&gt;
&lt;li&gt;The Core Concept: File-Based Routing&lt;/li&gt;
&lt;li&gt;The Essential Files Inside app/&lt;/li&gt;
&lt;li&gt;Layouts: The Secret Weapon&lt;/li&gt;
&lt;li&gt;Loading and Error States&lt;/li&gt;
&lt;li&gt;Error Boundaries: One Important Limitation&lt;/li&gt;
&lt;li&gt;Handling 404 Pages with not-found.tsx&lt;/li&gt;
&lt;li&gt;Dynamic Routes&lt;/li&gt;
&lt;li&gt;Understanding Route Groups&lt;/li&gt;
&lt;li&gt;A Real-World Folder Structure&lt;/li&gt;
&lt;li&gt;Common Mistakes Developers Make&lt;/li&gt;
&lt;li&gt;Final Thoughts&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why the &lt;code&gt;app/&lt;/code&gt; Directory Matters
&lt;/h2&gt;

&lt;p&gt;When Next.js introduced the &lt;strong&gt;App Router&lt;/strong&gt;, it wasn’t just a new folder.&lt;/p&gt;

&lt;p&gt;It was a shift in how we design React applications.&lt;/p&gt;

&lt;p&gt;Instead of scattering logic across multiple layers, the &lt;code&gt;app/&lt;/code&gt; directory organizes your app around &lt;strong&gt;routes and UI segments&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think of it like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;URL → Folder → UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach makes large applications easier to reason about.&lt;/p&gt;

&lt;p&gt;Instead of asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Where is the component for this page?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You simply look at the &lt;strong&gt;folder that matches the route&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Concept: File-Based Routing
&lt;/h2&gt;

&lt;p&gt;Routing in the &lt;code&gt;app/&lt;/code&gt; directory is simple.&lt;/p&gt;

&lt;p&gt;Folders define routes.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  page.tsx
  about/
    page.tsx
  dashboard/
    page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/           → page.tsx
/about      → about/page.tsx
/dashboard  → dashboard/page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A basic page file looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello Next.js&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;No router configuration required.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Essential Files Inside &lt;code&gt;app/&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Next.js uses &lt;strong&gt;special filenames&lt;/strong&gt; to control behavior.&lt;/p&gt;

&lt;p&gt;Here are the ones you'll use most.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;page.tsx&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Defines a &lt;strong&gt;route UI&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Dashboard&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every accessible route must contain a &lt;code&gt;page.tsx&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;layout.tsx&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Layouts wrap multiple pages and &lt;strong&gt;persist during navigation&lt;/strong&gt;.&lt;br&gt;
Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  layout.tsx
  dashboard/
    layout.tsx
    page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example layout:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactNode&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Navigation&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;nav&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;main&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Layouts &lt;strong&gt;do not re-render during navigation&lt;/strong&gt;, making them perfect for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigation bars&lt;/li&gt;
&lt;li&gt;Sidebars&lt;/li&gt;
&lt;li&gt;Shared UI&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Layouts: The Secret Weapon
&lt;/h2&gt;

&lt;p&gt;One of the biggest advantages of the App Router is &lt;strong&gt;nested layouts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Example structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  layout.tsx
  dashboard/
    layout.tsx
    analytics/
      page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rendering flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Root Layout
   ↓
Dashboard Layout
   ↓
Analytics Page
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows you to build &lt;strong&gt;complex UI structures without prop-drilling or layout duplication&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Loading and Error States
&lt;/h2&gt;

&lt;p&gt;Next.js lets you define &lt;strong&gt;route-level UI states&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;loading.tsx&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Displayed while a route loads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Loading&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Loading...&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;skeleton screens&lt;/li&gt;
&lt;li&gt;streaming UI&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;code&gt;error.tsx&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Handles errors inside a route segment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;// Error boundaries must be Client Components&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Something went wrong&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents the entire app from crashing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Error Boundaries: One Important Limitation
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;error.tsx&lt;/code&gt; file works as a &lt;strong&gt;React Error Boundary&lt;/strong&gt; for a route segment.&lt;/p&gt;

&lt;p&gt;But there's an important limitation many developers miss.&lt;/p&gt;

&lt;p&gt;Error boundaries &lt;strong&gt;do not catch errors inside event handlers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They only catch errors that happen during:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rendering&lt;/li&gt;
&lt;li&gt;server component execution&lt;/li&gt;
&lt;li&gt;data fetching&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example error boundary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;Error&lt;/span&gt;
  &lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Something went wrong.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        Try again
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Errors thrown inside event handlers must still be handled manually.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Boom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of &lt;code&gt;error.tsx&lt;/code&gt; as a &lt;strong&gt;UI safety net&lt;/strong&gt;, not a full error handling system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Handling 404 Pages with &lt;code&gt;not-found.tsx&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Every production app needs a &lt;strong&gt;good 404 experience&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Next.js handles this with &lt;code&gt;not-found.tsx&lt;/code&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Page not found&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h2&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;The content you're looking for doesn't exist.&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To trigger it, use the &lt;code&gt;notFound()&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;notFound&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next/navigation&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;notFound&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can define &lt;strong&gt;multiple &lt;code&gt;not-found.tsx&lt;/code&gt; files&lt;/strong&gt; at different levels.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  not-found.tsx
  dashboard/
    not-found.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;closest one in the route tree wins&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dynamic Routes
&lt;/h2&gt;

&lt;p&gt;Dynamic routes use &lt;strong&gt;square brackets&lt;/strong&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  blog/
    [slug]/
      page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;URLs generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/blog/my-first-post
/blog/nextjs-routing
/blog/react-performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;BlogPost&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;params&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also combine it with &lt;strong&gt;static generation&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Multiple Dynamic Segments
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  shop/
    [category]/
      [product]/
        page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/shop/laptops/macbook-pro
/shop/phones/iphone-15
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ProductPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;params&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;
    &lt;span class="na"&gt;product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Category: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;category&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Catch-All Routes
&lt;/h3&gt;

&lt;p&gt;Sometimes you need flexible routes.&lt;/p&gt;

&lt;p&gt;Next.js supports &lt;strong&gt;catch-all segments&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[...slug]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  docs/
    [...slug]/
      page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Supported URLs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/docs
/docs/getting-started
/docs/guides/routing
/docs/api/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;DocsPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;params&lt;/span&gt;
&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Optional Catch-All Routes
&lt;/h3&gt;

&lt;p&gt;Optional version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[[...slug]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This supports both:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/docs
/docs/routing
/docs/config/api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All handled by the same page.&lt;/p&gt;




&lt;h2&gt;
  
  
  Understanding Route Groups
&lt;/h2&gt;

&lt;p&gt;Route Groups help organize code &lt;strong&gt;without affecting URLs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;They use parentheses.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  (marketing)/
    page.tsx
    about/
      page.tsx

  (dashboard)/
    dashboard/
      page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generated URLs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/
/about
/dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The group names &lt;strong&gt;never appear in the URL&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Why use them?&lt;/p&gt;

&lt;p&gt;Because real applications often have &lt;strong&gt;multiple app sections&lt;/strong&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  (marketing)/
    layout.tsx
    page.tsx
    pricing/
      page.tsx

  (app)/
    layout.tsx
    dashboard/
      page.tsx
    settings/
      page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;different layouts&lt;/li&gt;
&lt;li&gt;different providers&lt;/li&gt;
&lt;li&gt;different UI structures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;without polluting URLs.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Real-World Folder Structure
&lt;/h2&gt;

&lt;p&gt;Here’s a scalable structure used in production projects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app/
  layout.tsx
  page.tsx

  (marketing)/
    page.tsx
    about/
      page.tsx

  (dashboard)/
    dashboard/
      layout.tsx
      page.tsx
      analytics/
        page.tsx
      settings/
        page.tsx

  blog/
    page.tsx
    [slug]/
      page.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps &lt;strong&gt;marketing pages&lt;/strong&gt;, &lt;strong&gt;application UI&lt;/strong&gt;, and &lt;strong&gt;content routes&lt;/strong&gt; clearly separated.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Mistakes Developers Make
&lt;/h2&gt;

&lt;p&gt;When I mentor developers using Next.js, these are the issues I see most often.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Mixing &lt;code&gt;pages/&lt;/code&gt; and &lt;code&gt;app/&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;While technically possible, it creates confusion.&lt;/p&gt;

&lt;p&gt;If you start with &lt;code&gt;app/&lt;/code&gt;, &lt;strong&gt;commit to it&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Over-nesting folders
&lt;/h3&gt;

&lt;p&gt;Deep structures become hard to maintain.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dashboard/analytics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dashboard/features/analytics/pages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. Ignoring layouts
&lt;/h3&gt;

&lt;p&gt;Layouts are one of the &lt;strong&gt;most powerful features&lt;/strong&gt; of the App Router.&lt;/p&gt;

&lt;p&gt;Use them.&lt;/p&gt;

&lt;p&gt;They dramatically simplify architecture.&lt;/p&gt;




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

&lt;p&gt;The &lt;code&gt;app/&lt;/code&gt; directory might feel unfamiliar at first.&lt;/p&gt;

&lt;p&gt;But once it clicks, it becomes &lt;strong&gt;one of the cleanest ways to structure React applications&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of wrestling with routing configuration, global wrappers, and layout duplication, you get a &lt;strong&gt;clear, predictable architecture&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Folders represent routes&lt;/li&gt;
&lt;li&gt;special files control behavior&lt;/li&gt;
&lt;li&gt;layouts manage shared UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And suddenly your project feels a lot more… &lt;strong&gt;Zen&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;If this article helped you understand the Next.js &lt;code&gt;app/&lt;/code&gt; directory better:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leave a &lt;strong&gt;❤️ reaction&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Drop a &lt;strong&gt;🦄 unicorn&lt;/strong&gt; if you love Next.js&lt;/li&gt;
&lt;li&gt;Share in the comments &lt;strong&gt;how you structure your projects&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And if you enjoy content like this, feel free to &lt;strong&gt;follow me here on DEV&lt;/strong&gt; for more posts about &lt;strong&gt;Next.js, architecture, and developer productivity&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;EDIT: A few people asked for an Italian version of this article.&lt;br&gt;
You can read it here: &lt;a href="https://dev.to/gavincettolo/nextjs-folder-zen-padroneggiare-la-directory-app-485k"&gt;Next.js Folder Zen: Padroneggiare la Directory app/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>react</category>
    </item>
    <item>
      <title>Il codice non si licenzia, ma le persone sì: Clean Code, Debito Tecnico e Bus Factor</title>
      <dc:creator>Gavin Cettolo</dc:creator>
      <pubDate>Wed, 11 Mar 2026 08:30:00 +0000</pubDate>
      <link>https://dev.to/gavincettolo/il-codice-non-si-licenzia-ma-le-persone-si-perche-il-clean-code-protegge-la-tua-azienda-dal-14d</link>
      <guid>https://dev.to/gavincettolo/il-codice-non-si-licenzia-ma-le-persone-si-perche-il-clean-code-protegge-la-tua-azienda-dal-14d</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Il debito tecnico non è solo un fastidio per gli sviluppatori: è un &lt;strong&gt;rischio aziendale con interessi composti&lt;/strong&gt;. Quando gli sviluppatori lasciano l’azienda, spesso si portano via il &lt;em&gt;“perché”&lt;/em&gt; dietro al codice.&lt;/p&gt;

&lt;p&gt;Il Clean Code non riguarda la perfezione: riguarda &lt;strong&gt;mantenere la conoscenza nel sistema&lt;/strong&gt;, invece che nella testa di qualcuno.&lt;br&gt;&lt;br&gt;
This article is also available in &lt;a href="https://dev.to/gavincettolo/code-doesnt-quit-but-people-do-why-clean-code-protects-your-company-from-technical-debt-41k2"&gt;English&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Poco tempo fa ho terminato il mio MBA e, guardando il mio lavoro anche da una prospettiva più business, sono arrivato a una conclusione interessante: &lt;strong&gt;sviluppatori&lt;/strong&gt; e &lt;strong&gt;stakeholder&lt;/strong&gt; hanno in realtà paura della stessa identica cosa, ma la descrivono con parole diverse.&lt;/p&gt;

&lt;p&gt;Benvenuti nel &lt;strong&gt;Bus Factor&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Una piccola realizzazione durante l’MBA
&lt;/h2&gt;

&lt;p&gt;Ho recentemente concluso il mio &lt;strong&gt;MBA&lt;/strong&gt; e, tra fogli di calcolo, strategie e discussioni sul posizionamento di mercato, ho avuto una piccola illuminazione.&lt;/p&gt;

&lt;p&gt;Mi sono reso conto che &lt;strong&gt;sviluppatori e business stakeholder spesso parlano lingue completamente diverse&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Noi sviluppatori parliamo di:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refactoring e pattern
&lt;/li&gt;
&lt;li&gt;Debito tecnico
&lt;/li&gt;
&lt;li&gt;Qualità del codice
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Il lato business invece parla di:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mitigazione del rischio
&lt;/li&gt;
&lt;li&gt;Turnover e ROI
&lt;/li&gt;
&lt;li&gt;Scalabilità e produttività
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Slide diverse, riunioni diverse, caffè diversi. Ma il punto è questo: &lt;strong&gt;in realtà abbiamo paura della stessa identica cosa&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Il Bus Factor
&lt;/h2&gt;

&lt;p&gt;Il &lt;strong&gt;Bus Factor&lt;/strong&gt; risponde a una domanda un po’ inquietante:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Quante persone possono lasciare il progetto prima che diventi un problema serio?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Se la risposta è &lt;strong&gt;una&lt;/strong&gt;, ho una brutta notizia per te. Il tuo progetto ha un Bus Factor di 1 e la tua azienda sta praticamente gestendo una &lt;strong&gt;situazione di ostaggio software&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Questo succede più spesso di quanto tendiamo ad ammettere.&lt;/p&gt;

&lt;p&gt;Un solo sviluppatore sa:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Come funziona davvero il flusso di autenticazione
&lt;/li&gt;
&lt;li&gt;Perché la logica di fatturazione richiede tre tentativi e una preghiera silenziosa al server
&lt;/li&gt;
&lt;li&gt;Cosa ci fa ancora lì quell’"hack temporaneo" del 2019
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E all'improvviso quello sviluppatore se ne va.&lt;/p&gt;

&lt;p&gt;Nuovo lavoro.&lt;br&gt;
Nuova città.&lt;br&gt;
Magari un allevamento di pecore in Nuova Zelanda.&lt;/p&gt;

&lt;p&gt;E così, all'improvviso...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;l’azienda perde letteralmente una parte del suo cervello&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Amnesia aziendale
&lt;/h2&gt;

&lt;p&gt;La &lt;strong&gt;Corporate Amnesia&lt;/strong&gt; si verifica quando gli sviluppatori lasciano l’azienda portando con sé la &lt;strong&gt;conoscenza istituzionale&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Contesto:&lt;/strong&gt; perché è stata scelta quella tecnologia o quell’architettura
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vincoli:&lt;/strong&gt; trappole nascoste e aree fragili del codice
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trade-off:&lt;/strong&gt; compromessi e decisioni prese nel tempo
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anche la migliore documentazione può diventare obsoleta se non viene aggiornata costantemente.&lt;/p&gt;

&lt;p&gt;Se il codice assomiglia a un &lt;strong&gt;museo di spaghetti sperimentali&lt;/strong&gt;, tutta quella conoscenza si diluisce o scompare. Il prodotto esiste ancora, ma nessuno capisce davvero &lt;em&gt;come&lt;/em&gt; funzioni.&lt;/p&gt;

&lt;p&gt;E questo non è solo un problema tecnico, è un &lt;strong&gt;rischio economico serio&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Il fantasma degli sviluppatori del passato
&lt;/h2&gt;

&lt;p&gt;Ogni sviluppatore ha vissuto questo momento.&lt;/p&gt;

&lt;p&gt;Apri un file.&lt;br&gt;&lt;br&gt;
Scorri.&lt;br&gt;&lt;br&gt;
E scorri ancora.&lt;/p&gt;

&lt;p&gt;Poi lo trovi: un &lt;strong&gt;&lt;code&gt;useEffect()&lt;/code&gt; da 500 righe&lt;/strong&gt;, senza commenti, con variabili chiamate &lt;code&gt;temp&lt;/code&gt;, &lt;code&gt;data2&lt;/code&gt; e &lt;code&gt;finalFinalVersion&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Controlli la cronologia Git.&lt;/p&gt;

&lt;p&gt;L’autore? Ha lasciato l’azienda due anni fa. Forse ora alleva pecore in Nuova Zelanda.&lt;/p&gt;

&lt;p&gt;Stai guardando una &lt;strong&gt;casa infestata di codice&lt;/strong&gt;: troppo rischiosa da cancellare, impossibile da modificare con sicurezza.&lt;/p&gt;

&lt;p&gt;Questo è il &lt;strong&gt;Fantasma degli Sviluppatori del Passato&lt;/strong&gt;, e costa all’azienda migliaia di euro in produttività persa ogni giorno.&lt;/p&gt;




&lt;h2&gt;
  
  
  Clean Code come trasferimento di conoscenza
&lt;/h2&gt;

&lt;p&gt;È qui che Clean Code cambia prospettiva.&lt;/p&gt;

&lt;p&gt;Il Clean Code non è estetica: è &lt;strong&gt;comunicazione strategica&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Quando il codice è pulito, la conoscenza rimane nel sistema anche quando le persone se ne vanno. Ogni sviluppatore futuro può capire:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cosa fa il codice
&lt;/li&gt;
&lt;li&gt;Perché esiste
&lt;/li&gt;
&lt;li&gt;Come interagisce con il resto del sistema &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;senza fissare un incontro con esperti di archeologia. &lt;/p&gt;

&lt;p&gt;Prendiamo questo esempio:&lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ Il modo criptico
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;processData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✅ Il modo chiaro
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getActiveUsersWithHighScore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ACTIVE_THRESHOLD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ACTIVE_THRESHOLD&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La logica è la stessa, ma la seconda versione &lt;strong&gt;comunica chiaramente l’intento&lt;/strong&gt;. La conoscenza rimane nel codice, non solo nella testa di uno sviluppatore.&lt;/p&gt;




&lt;h2&gt;
  
  
  Il refactoring come assicurazione
&lt;/h2&gt;

&lt;p&gt;Una delle frasi più comuni nelle aziende è:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Non abbiamo tempo per fare refactoring"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ma da una prospettiva aziendale, la vera domanda dovrebbe essere un'altra:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Quanto ci costerà quando nessuno capirà più questo codice?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ogni ora spesa per trasformare una &lt;strong&gt;funzione Frankenstein&lt;/strong&gt; in qualcosa di leggibile non è tempo sprecato.&lt;/p&gt;

&lt;p&gt;È un investimento in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Velocità di onboarding:&lt;/strong&gt; i nuovi sviluppatori diventano produttivi in giorni, non mesi
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Autonomia del team:&lt;/strong&gt; chiunque può lavorare su qualsiasi parte del sistema
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resilienza:&lt;/strong&gt; quando qualcuno lascia l’azienda, il progetto sopravvive
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In altre parole: il refactoring è letteralmente un'&lt;strong&gt;assicurazione contro l'amnesia aziendale&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Il codice è documentazione
&lt;/h2&gt;

&lt;p&gt;Quando è scritto bene, il codice è la miglior documentazione possibile. Nomi chiari, funzioni piccole e architetture comprensibili &lt;strong&gt;preservano la conoscenza&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A differenza della documentazione statica, il codice pulito non diventa obsoleto per abbandono: evolve insieme al sistema.&lt;/p&gt;




&lt;h2&gt;
  
  
  Clean Code nell'era dell'IA
&lt;/h2&gt;

&lt;p&gt;Oggi stiamo entrando in una nuova fase dello sviluppo software.&lt;/p&gt;

&lt;p&gt;Gli strumenti di IA, come gli assistenti al codice, possono generare funzioni, componenti e persino interi moduli in pochi secondi.&lt;/p&gt;

&lt;p&gt;Questo cambia la produttività, ma &lt;strong&gt;aumenta anche la posta in gioco per la qualità del codice&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Se l'IA genera codice su un'architettura disordinata, semplicemente &lt;strong&gt;accelera il caos&lt;/strong&gt;, ma quando la base di codice è pulita e ben strutturata, l'IA diventa incredibilmente potente:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;comprende l'architettura più velocemente&lt;/li&gt;
&lt;li&gt;genera suggerimenti migliori&lt;/li&gt;
&lt;li&gt;riduce i tempi di sviluppo senza aumentare la complessità&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In altre parole, &lt;strong&gt;il codice pulito diventa la base per un efficace sviluppo assistito dall'IA&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Un codice scadente rallenta gli esseri umani e un codice scadente rallenta anche l'IA.&lt;/p&gt;




&lt;h2&gt;
  
  
  Messaggio chiave
&lt;/h2&gt;

&lt;p&gt;Se c’è una sola cosa da ricordare è questa:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Il Clean Code non riguarda l’eleganza: riguarda la memoria organizzativa.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Più a lungo vive un progetto, più questo diventa importante.&lt;/p&gt;




&lt;h2&gt;
  
  
  Pensiero finale
&lt;/h2&gt;

&lt;p&gt;Dopo il mio MBA, una cosa è diventata molto chiara: &lt;strong&gt;il Clean Code è una strategia aziendale&lt;/strong&gt;. Protegge dalla perdita di conoscenza, riduce l’attrito nell’onboarding e rende i team più resilienti ai cambiamenti.&lt;/p&gt;

&lt;p&gt;Dato che gli sviluppatori cambiano lavoro molto più spesso di quanto il codice cambi repository, scrivere codice pulito è &lt;strong&gt;uno degli investimenti migliori che un’azienda possa fare&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Una domanda per te
&lt;/h2&gt;

&lt;p&gt;Quanta parte del tuo sistema vive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nel &lt;strong&gt;codebase&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Nella &lt;strong&gt;testa di qualcuno&lt;/strong&gt;?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Condividi la tua esperienza nei commenti!&lt;/p&gt;

</description>
      <category>cleancode</category>
      <category>softwareengineering</category>
      <category>carriera</category>
      <category>techleadership</category>
    </item>
    <item>
      <title>Code doesn’t quit, but people do: Clean Code, Technical Debt, and the Bus Factor</title>
      <dc:creator>Gavin Cettolo</dc:creator>
      <pubDate>Tue, 10 Mar 2026 08:30:00 +0000</pubDate>
      <link>https://dev.to/gavincettolo/code-doesnt-quit-but-people-do-why-clean-code-protects-your-company-from-technical-debt-41k2</link>
      <guid>https://dev.to/gavincettolo/code-doesnt-quit-but-people-do-why-clean-code-protects-your-company-from-technical-debt-41k2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Technical debt isn’t just a developer inconvenience, it’s a &lt;strong&gt;business risk with compound interest&lt;/strong&gt;. When developers leave, they often take the &lt;em&gt;“why”&lt;/em&gt; behind the code with them.&lt;/p&gt;

&lt;p&gt;Clean Code isn’t about perfection: it’s about &lt;strong&gt;preserving knowledge inside the system&lt;/strong&gt;, instead of inside someone’s head.&lt;br&gt;&lt;br&gt;
Questo articolo è disponibile anche in &lt;a href="https://dev.to/gavincettolo/il-codice-non-si-licenzia-ma-le-persone-si-perche-il-clean-code-protegge-la-tua-azienda-dal-14d"&gt;Italiano&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not long ago I finished my MBA and, looking at my work from a more business-oriented perspective, I came to an interesting realization: &lt;strong&gt;developers&lt;/strong&gt; and &lt;strong&gt;stakeholders&lt;/strong&gt; are actually afraid of the exact same thing, they just describe it using different words.&lt;/p&gt;

&lt;p&gt;Welcome to the &lt;strong&gt;Bus Factor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This article explores how &lt;strong&gt;Clean Code, technical debt, and knowledge transfer&lt;/strong&gt; affect real business risks like developer turnover, onboarding speed, and team scalability.&lt;/p&gt;




&lt;h2&gt;
  
  
  A small MBA realization
&lt;/h2&gt;

&lt;p&gt;I recently closed my &lt;strong&gt;MBA&lt;/strong&gt;, and among all the talk of spreadsheets and market positioning, I had a "Eureka" moment.  &lt;/p&gt;

&lt;p&gt;I realized that &lt;strong&gt;developers and business stakeholders often speak completely different languages&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We (the devs) talk about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refactoring and patterns
&lt;/li&gt;
&lt;li&gt;Technical debt
&lt;/li&gt;
&lt;li&gt;Code quality
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Meanwhile, the business side talks about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Risk mitigation
&lt;/li&gt;
&lt;li&gt;Turnover and ROI
&lt;/li&gt;
&lt;li&gt;Scalability and productivity
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Different slides, different meetings, different coffee. But the kicker: &lt;strong&gt;we are actually afraid of the exact same thing&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bus Factor
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Bus Factor&lt;/strong&gt; answers a slightly dark question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How many people can leave before the project becomes a serious risk?&lt;/em&gt;  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer is &lt;strong&gt;one&lt;/strong&gt;, I have bad news for you. Your project has a Bus Factor of 1, and your company is basically running a &lt;strong&gt;software hostage situation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This happens more often than we'd like to admit.&lt;/p&gt;

&lt;p&gt;One developer knows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How the authentication flow actually works
&lt;/li&gt;
&lt;li&gt;Why the billing logic requires three retries and a silent prayer
&lt;/li&gt;
&lt;li&gt;What that "temporary hack" from 2019 is still doing there
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And suddenly that developer leaves.&lt;/p&gt;

&lt;p&gt;New job.&lt;br&gt;&lt;br&gt;
New city.&lt;br&gt;&lt;br&gt;
Maybe a goat farm in New Zealand.&lt;/p&gt;

&lt;p&gt;And just like that…&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;the company loses part of its brain.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Corporate Amnesia
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Corporate Amnesia&lt;/strong&gt; happens when developers leave, taking with them &lt;strong&gt;institutional knowledge&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Context:&lt;/strong&gt; Why this technology or design was chosen
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constraints:&lt;/strong&gt; Hidden pitfalls and fragile areas of the code
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trade-offs:&lt;/strong&gt; Decisions and compromises made over time
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even the best documentation can become outdated if not constantly maintained.  &lt;/p&gt;

&lt;p&gt;If the codebase looks like a &lt;strong&gt;museum of experimental spaghetti&lt;/strong&gt;, all that knowledge is diluted or lost. The product exists, but nobody fully understands &lt;em&gt;how&lt;/em&gt; it works anymore. &lt;/p&gt;

&lt;p&gt;That is not just a technical problem, that's a &lt;strong&gt;serious financial risk&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Ghost of Developers Past
&lt;/h2&gt;

&lt;p&gt;Every developer has experienced this:&lt;/p&gt;

&lt;p&gt;You open a file.&lt;br&gt;&lt;br&gt;
You scroll.&lt;br&gt;&lt;br&gt;
And scroll again.  &lt;/p&gt;

&lt;p&gt;Then you find it: A &lt;strong&gt;500-line &lt;code&gt;useEffect()&lt;/code&gt;&lt;/strong&gt;, with no comments and variables like &lt;code&gt;temp&lt;/code&gt;, &lt;code&gt;data2&lt;/code&gt;, and &lt;code&gt;finalFinalVersion&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;Git history? The author left the company two years ago. Possibly raising goats in New Zealand.  &lt;/p&gt;

&lt;p&gt;You’re staring at a &lt;strong&gt;haunted codehouse&lt;/strong&gt;: too risky to delete, impossible to touch safely.&lt;br&gt;&lt;br&gt;
This is the &lt;strong&gt;Ghost of Developers Past&lt;/strong&gt;, silently costing thousands in lost productivity every day.&lt;/p&gt;




&lt;h2&gt;
  
  
  Clean Code as Knowledge Transfer
&lt;/h2&gt;

&lt;p&gt;This is where Clean Code changes perspective.&lt;/p&gt;

&lt;p&gt;Clean Code is not aesthetic, it’s &lt;strong&gt;strategic communication&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;When code is clean, knowledge stays in the system even when people leave. Every future developer understands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What the code does
&lt;/li&gt;
&lt;li&gt;Why it exists
&lt;/li&gt;
&lt;li&gt;How it interacts with the system &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;without scheduling a meeting with archaeology experts. &lt;/p&gt;

&lt;p&gt;Let's take this example: &lt;/p&gt;

&lt;h3&gt;
  
  
  ❌ The Cryptic Way
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;processData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
      &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ✅ The Clean Way
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getActiveUsersWithHighScore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ACTIVE_THRESHOLD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ACTIVE_THRESHOLD&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The logic is the same, but the second version &lt;strong&gt;communicates the intent&lt;/strong&gt;. Knowledge is preserved inside the code, not just in a developer’s head.&lt;/p&gt;




&lt;h2&gt;
  
  
  Refactoring as Insurance
&lt;/h2&gt;

&lt;p&gt;There's a common argument in many companies:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We don't have time for refactoring"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But from a business perspective, the real question should be different:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How expensive will it be when nobody understands this code anymore?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every hour spent turning a &lt;strong&gt;Frankenstein function&lt;/strong&gt; into something readable is not wasted time.&lt;/p&gt;

&lt;p&gt;It's an investment in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Onboarding Speed:&lt;/strong&gt; New hires become productive in days instead of months
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team Autonomy:&lt;/strong&gt; Anyone can safely modify any part of the system
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resilience:&lt;/strong&gt; When developers leave, the project survives
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words: refactoring is literally an &lt;strong&gt;insurance against corporate amnesia&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Code is Documentation
&lt;/h2&gt;

&lt;p&gt;Code is the best documentation when written well. Clear naming, small focused functions, and understandable architecture &lt;strong&gt;preserve knowledge&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;Unlike static docs, clean code doesn’t get outdated by neglectit evolves with the system.&lt;/p&gt;




&lt;h2&gt;
  
  
  Clean Code in the age of AI
&lt;/h2&gt;

&lt;p&gt;Today we are entering a new phase of software development.&lt;/p&gt;

&lt;p&gt;AI tools, like code assistants, can generate functions, components, and even entire modules in seconds.&lt;/p&gt;

&lt;p&gt;This changes productivity, but it also &lt;strong&gt;raises the stakes for code quality&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If AI generates code on top of a messy architecture, it simply &lt;strong&gt;accelerates chaos&lt;/strong&gt;, but when the codebase is clean and well structured, AI becomes incredibly powerful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it understands the architecture faster&lt;/li&gt;
&lt;li&gt;it generates better suggestions&lt;/li&gt;
&lt;li&gt;it reduces development time without increasing complexity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, &lt;strong&gt;Clean Code becomes the foundation for effective AI-assisted development&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Bad code slows humans and bad code slows AI too.&lt;/p&gt;




&lt;h2&gt;
  
  
  Mini takeaway
&lt;/h2&gt;

&lt;p&gt;If there's one takeaway:  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Clean Code isn’t about elegance, it’s about organizational memory.&lt;/strong&gt;  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The longer your project exists, the more valuable this becomes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;After my MBA, one thing became clear: &lt;strong&gt;Clean Code is a business strategy&lt;/strong&gt;. It protects against knowledge loss, reduces onboarding friction, and makes teams resilient to change.  &lt;/p&gt;

&lt;p&gt;Since developers change jobs more often than code changes repositories, clean code is &lt;strong&gt;one of the best investments a company can make&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  One question for you
&lt;/h2&gt;

&lt;p&gt;How much of your system lives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inside the &lt;strong&gt;codebase&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Inside someone's &lt;strong&gt;head&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Share your thoughts in the comments!&lt;/p&gt;




&lt;p&gt;EDIT: A few people asked for an Italian version of this article.&lt;br&gt;
You can read it here:&lt;br&gt;
&lt;a href="https://dev.to/gavincettolo/il-codice-non-si-licenzia-ma-le-persone-si-perche-il-clean-code-protegge-la-tua-azienda-dal-14d"&gt;https://dev.to/gavincettolo/il-codice-non-si-licenzia-ma-le-persone-si-perche-il-clean-code-protegge-la-tua-azienda-dal-14d&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  A quick thought experiment
&lt;/h2&gt;

&lt;p&gt;Imagine that tomorrow one of your senior developers leaves the company.&lt;/p&gt;

&lt;p&gt;How many parts of the system would suddenly become a &lt;strong&gt;black box&lt;/strong&gt;?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;authentication&lt;/li&gt;
&lt;li&gt;billing&lt;/li&gt;
&lt;li&gt;deployment pipelines&lt;/li&gt;
&lt;li&gt;legacy integrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the answer is "too many", the problem is not the developer leaving.&lt;/p&gt;

&lt;p&gt;The problem is that &lt;strong&gt;knowledge lives in people's heads instead of the codebase&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That’s exactly what Clean Code tries to prevent.&lt;/p&gt;

</description>
      <category>cleancode</category>
      <category>softwareengineering</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Hellooo devs 👋</title>
      <dc:creator>Gavin Cettolo</dc:creator>
      <pubDate>Thu, 05 Mar 2026 17:55:22 +0000</pubDate>
      <link>https://dev.to/gavincettolo/hellooo-devs-3o2p</link>
      <guid>https://dev.to/gavincettolo/hellooo-devs-3o2p</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I'm Gavin Cettolo, a developer since 2017, builder and problem solver. I mainly work with React and Next.js, have experience coordinating projects and dev teams, and recently completed an MBA with honors to better understand the business dynamics behind every line of code.  &lt;/p&gt;

&lt;p&gt;I’ve decided to start publishing on Dev.to to talk about &lt;em&gt;React&lt;/em&gt;, &lt;em&gt;Clean Code&lt;/em&gt;, &lt;em&gt;AI&lt;/em&gt; in development, &lt;em&gt;OOP patterns&lt;/em&gt;, &lt;em&gt;system design interviews&lt;/em&gt;, and &lt;em&gt;project organization&lt;/em&gt;. My goal is to share what I learn and, most importantly, to learn better by explaining things clearly. Ideally, you’ll read something here and think, “Ah, that’s interesting.”&lt;/p&gt;

&lt;p&gt;Questo articolo è anche disponibile in &lt;a href="https://dev.to/gavincettolo/buuuongiorno-devs-nn9"&gt;Italiano&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Who I Am
&lt;/h2&gt;

&lt;p&gt;Hi everyone,&lt;br&gt;&lt;br&gt;
I’m Gavin, and this is my way of politely knocking on Dev.to’s door before diving into technical articles.&lt;/p&gt;

&lt;p&gt;I consider myself a &lt;em&gt;builder&lt;/em&gt; and a &lt;em&gt;problem solver&lt;/em&gt;. I like creating solutions that are useful, well-structured, and maintainable. Coding officially became my job back in March 2017, but the curiosity started much earlier. As a kid, I used to take computers apart, copy code from random tutorials, and spend more time experimenting than actually playing games.&lt;/p&gt;

&lt;p&gt;Over the years, I’ve worked with several technologies: Java, .NET, Angular, jQuery, and more. Each one taught me something valuable. Then I discovered React, and it won me over.&lt;/p&gt;

&lt;p&gt;Its flexibility, mindset, and community made development feel cleaner and more modular. Next.js naturally followed: better project structure, easier SEO handling, elegant rendering strategies, and less friction between idea and production.&lt;/p&gt;

&lt;p&gt;Today I move between frontend and backend with a strong focus on code quality. I’ve also coordinated projects and development teams over time. I genuinely enjoy working with people as much as I enjoy working with code: running constructive code reviews, improving communication, and helping projects stay structured as they scale.&lt;/p&gt;

&lt;p&gt;The startup world taught me one simple thing: change is constant. New features, inevitable refactors, unexpected bugs. If you don’t enjoy continuous learning, this might not be the right field for you.&lt;/p&gt;




&lt;h2&gt;
  
  
  Clean Code as a Mindset
&lt;/h2&gt;

&lt;p&gt;I don’t see Clean Code as an aesthetic preference. It’s a form of respect.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Respect for the person who will read your code after you.
&lt;/li&gt;
&lt;li&gt;Respect for your future self.
&lt;/li&gt;
&lt;li&gt;Respect for the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For me, it means writing code that can be understood without decoding cryptic comments. Functions with a clear responsibility. Names that explain instead of confuse. Structures that don’t create anxiety three months later.&lt;/p&gt;

&lt;p&gt;I follow classic principles, but I don’t treat them as dogma. Context matters. The real goal is always the same: readable, testable, maintainable code that doesn’t cause unnecessary friction.&lt;/p&gt;




&lt;h2&gt;
  
  
  AI in Development
&lt;/h2&gt;

&lt;p&gt;I use AI as a support tool, not as an autopilot.&lt;/p&gt;

&lt;p&gt;It helps me generate simple snippets, perform small refactors, and unblock ideas when I get stuck. But the responsibility remains mine. AI accelerates the process, it doesn’t replace reasoning.&lt;/p&gt;

&lt;p&gt;In the coming years, I believe the real difference won’t be between developers who use AI and those who don’t. It will be between those who use it consciously and those who use it passively.&lt;/p&gt;




&lt;h2&gt;
  
  
  An MBA to Understand What’s Beyond the Code
&lt;/h2&gt;

&lt;p&gt;I recently completed a Master of Business Administration with top honors.&lt;/p&gt;

&lt;p&gt;It wasn’t a change of direction, but an expansion of perspective. Budgeting, strategy, organization, goal setting, resource management. Every piece of software lives inside a business context. Understanding that context changes how you make technical decisions.&lt;/p&gt;

&lt;p&gt;Writing a feature is one thing. Writing it while understanding why it exists and what business impact it has is another.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I’m Writing Here
&lt;/h2&gt;

&lt;p&gt;I write to share, but also to learn better.&lt;/p&gt;

&lt;p&gt;There’s a simple rule I’ve always found true: if you can explain something clearly, then you truly understand it. This blog is also a personal exercise in clarity.&lt;/p&gt;

&lt;p&gt;My plan is to publish one article per week, alternating topics. Some weeks will focus on React and Next.js, others on Clean Code, AI in development, OOP patterns, system design interviews, and reflections on organization and professional growth.&lt;/p&gt;

&lt;p&gt;I want to keep a consistent and sustainable rhythm. No content overload, just thoughtful, practical, and concrete articles.&lt;/p&gt;

&lt;p&gt;Here you’ll find content about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React and Next.js&lt;/li&gt;
&lt;li&gt;Clean Code and best practices&lt;/li&gt;
&lt;li&gt;OOP patterns&lt;/li&gt;
&lt;li&gt;System design interviews&lt;/li&gt;
&lt;li&gt;AI applied to development&lt;/li&gt;
&lt;li&gt;Organization, growth, and project dynamics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No guru mindset and no absolute truths. Just experience, experiments, mistakes, and continuous improvement.&lt;/p&gt;

&lt;p&gt;If you made it this far, thank you.&lt;br&gt;&lt;br&gt;
Feel free to introduce yourself in the comments or tell me what kind of content you’d like to read.&lt;/p&gt;

&lt;p&gt;See you soon.&lt;/p&gt;

&lt;p&gt;Gavin 🚀&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>cleancode</category>
      <category>career</category>
    </item>
    <item>
      <title>Buuuongiorno devs 👋</title>
      <dc:creator>Gavin Cettolo</dc:creator>
      <pubDate>Thu, 05 Mar 2026 17:55:09 +0000</pubDate>
      <link>https://dev.to/gavincettolo/buuuongiorno-devs-nn9</link>
      <guid>https://dev.to/gavincettolo/buuuongiorno-devs-nn9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Sono &lt;strong&gt;Gavin Cettolo&lt;/strong&gt;, sviluppatore dal 2017, builder e problem solver. Lavoro principalmente con &lt;strong&gt;React&lt;/strong&gt; e &lt;strong&gt;Next.js&lt;/strong&gt;, ho esperienza nel coordinamento di progetti e ho appena concluso un &lt;strong&gt;MBA&lt;/strong&gt; con il massimo dei voti per comprendere meglio le dinamiche aziendali dietro ogni riga di codice.  &lt;/p&gt;

&lt;p&gt;Ho deciso di iniziare a pubblicare su Dev.To per parlare di React, Clean Code, AI nello sviluppo, OOP patterns, system design interview e organizzazione del lavoro. Il mio obiettivo è condividere e, soprattutto, imparare meglio spiegando agli altri, magari strappandovi un "ah, interessante!"&lt;/p&gt;

&lt;p&gt;This article is also available in &lt;a href="https://dev.to/gavincettolo/hellooo-devs-3o2p"&gt;English&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Chi sono
&lt;/h2&gt;

&lt;p&gt;Ciao a tutti!&lt;br&gt;
sono Gavin, e questo è il mio modo per bussare educatamente alla porta di Dev.to prima di iniziare a parlare seriamente di codice.&lt;/p&gt;

&lt;p&gt;Mi definisco un &lt;em&gt;builder&lt;/em&gt; e un &lt;em&gt;problem solver&lt;/em&gt;: mi piace costruire soluzioni utili, ragionate e manutenibili. Scrivere codice è diventato un lavoro nel lontano marzo 2017, ma la passione e la curiosità sono nate molto prima: da ragazzino smontavo computer, copiavo codice da HTML.it cercando di capire perché funzionasse e passavo più tempo a fare esperimenti che a giocare.&lt;/p&gt;

&lt;p&gt;Negli anni ho lavorato con diverse tecnologie: Java, .NET, Angular, jQuery e altre ancora. Ognuna mi ha lasciato qualcosa. Poi è arrivato React, e mi ha conquistato.&lt;/p&gt;

&lt;p&gt;Per flessibilità, mentalità e community. Mi ha dato la sensazione di poter costruire in modo più pulito e modulare. Next.js è diventato il naturale compagno di viaggio: struttura migliore, SEO più gestibile, rendering elegante e meno frizione tra idea e produzione.&lt;/p&gt;

&lt;p&gt;Oggi mi muovo tra frontend e backend con una forte attenzione alla qualità del codice. Nel tempo ho coordinato progetti e team di sviluppo. Mi piace lavorare con le persone tanto quanto con l’editor: fare code review costruttive, migliorare la comunicazione e aiutare un progetto a restare ordinato anche quando cresce velocemente.&lt;/p&gt;

&lt;p&gt;Il mondo startup mi ha insegnato una cosa semplice: il cambiamento è continuo. Nuove feature, refactor inevitabili, bug che compaiono quando meno te lo aspetti. Se non ti piace imparare costantemente, sei nel posto sbagliato.&lt;/p&gt;




&lt;h2&gt;
  
  
  Clean Code come mentalità
&lt;/h2&gt;

&lt;p&gt;Non considero il Clean Code un vezzo estetico. È una forma di rispetto.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rispetto per chi leggerà quel codice dopo di te.
&lt;/li&gt;
&lt;li&gt;Rispetto per il tuo io futuro.
&lt;/li&gt;
&lt;li&gt;Rispetto per il progetto.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Per me significa scrivere codice che si capisca senza dover decifrare commenti criptici. Funzioni con una responsabilità chiara. Nomi che raccontano cosa fanno. Strutture che non generano ansia dopo tre mesi.&lt;/p&gt;

&lt;p&gt;Seguo i principi classici, ma senza trasformarli in religione. Il contesto conta. L’obiettivo è sempre lo stesso: codice leggibile, testabile e modificabile senza drammi.&lt;/p&gt;




&lt;h2&gt;
  
  
  AI nello sviluppo
&lt;/h2&gt;

&lt;p&gt;Uso l’AI come strumento di supporto, non come pilota automatico.&lt;/p&gt;

&lt;p&gt;Mi aiuta a generare snippet semplici, a fare piccoli refactor e a sbloccare idee quando mi incastro mentalmente. Ma la responsabilità resta mia. L’AI accelera il processo, non sostituisce il ragionamento.&lt;/p&gt;

&lt;p&gt;Credo che nei prossimi anni la vera differenza non sarà tra chi usa o non usa l’AI, ma tra chi la usa in modo consapevole e chi la usa in modo passivo.&lt;/p&gt;




&lt;h2&gt;
  
  
  Un MBA per capire cosa c’è oltre il codice
&lt;/h2&gt;

&lt;p&gt;Ho appena concluso un Master universitario in Business Administration (MBA) con il massimo dei voti.&lt;/p&gt;

&lt;p&gt;Non è stato un cambio di rotta, ma un ampliamento di prospettiva. Budget, strategia, organizzazione, obiettivi, gestione delle risorse. Ogni software vive dentro un contesto aziendale. Capire quel contesto cambia il modo in cui prendi decisioni tecniche.&lt;/p&gt;

&lt;p&gt;Scrivere una feature è una cosa. Scriverla sapendo perché esiste e quale impatto ha sul business è un’altra.&lt;/p&gt;




&lt;h2&gt;
  
  
  Perché scrivo qui
&lt;/h2&gt;

&lt;p&gt;Scrivo per condividere, ma anche per imparare meglio.&lt;/p&gt;

&lt;p&gt;C’è una regola semplice che ho sempre trovato vera: se sai spiegare qualcosa in modo chiaro, allora l’hai capita davvero. Questo blog è anche un esercizio personale di chiarezza.&lt;/p&gt;

&lt;p&gt;L’idea è pubblicare un articolo alla settimana, alternando gli argomenti. Un po’ di React e Next.js, un po’ di Clean Code, poi AI applicata allo sviluppo, OOP patterns, system design interview e qualche riflessione su organizzazione e crescita professionale.&lt;/p&gt;

&lt;p&gt;Voglio mantenere una cadenza costante e sostenibile. Niente pubblicazioni compulsive, ma contenuti pensati, concreti e utili.&lt;/p&gt;

&lt;p&gt;Qui troverai quindi contenuti su:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React e Next.js&lt;/li&gt;
&lt;li&gt;Clean Code e best practice&lt;/li&gt;
&lt;li&gt;OOP patterns&lt;/li&gt;
&lt;li&gt;System design interview&lt;/li&gt;
&lt;li&gt;AI applicata allo sviluppo&lt;/li&gt;
&lt;li&gt;Organizzazione, crescita e dinamiche di progetto&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Niente guru e niente verità assolute. Solo esperienza, esperimenti, errori e miglioramenti continui.&lt;/p&gt;

&lt;p&gt;Se sei arrivato fin qui, grazie davvero.&lt;br&gt;&lt;br&gt;
Se vuoi, presentati nei commenti o dimmi che tipo di contenuti ti piacerebbe leggere.&lt;/p&gt;

&lt;p&gt;A prestissimo!&lt;/p&gt;

&lt;p&gt;Gavin 🚀&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>cleancode</category>
      <category>career</category>
    </item>
  </channel>
</rss>
