<?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: Agustín Rodríguez</title>
    <description>The latest articles on DEV Community by Agustín Rodríguez (@agusrdz).</description>
    <link>https://dev.to/agusrdz</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%2F579811%2F58c25c93-c892-4f37-b26e-c91670e41a47.png</url>
      <title>DEV Community: Agustín Rodríguez</title>
      <link>https://dev.to/agusrdz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/agusrdz"/>
    <language>en</language>
    <item>
      <title>The Life Has No Shortcuts. VS Code Has Too Many.</title>
      <dc:creator>Agustín Rodríguez</dc:creator>
      <pubDate>Fri, 13 Feb 2026 01:51:20 +0000</pubDate>
      <link>https://dev.to/agusrdz/the-life-has-no-shortcuts-vs-code-has-too-many-p09</link>
      <guid>https://dev.to/agusrdz/the-life-has-no-shortcuts-vs-code-has-too-many-p09</guid>
      <description>&lt;p&gt;Every time you install a VS Code extension, something quiet happens in the background: new keyboard shortcuts show up. Nobody tells you. Nobody asks if you want them. They just appear, silently overriding what was there before.&lt;/p&gt;

&lt;p&gt;One day you press &lt;code&gt;Ctrl+Shift+P&lt;/code&gt; and something unexpected runs. Or &lt;code&gt;Cmd+D&lt;/code&gt; stops doing what it used to. You check your keybindings and find a mess - ten extensions fighting over the same keys, and you never chose any of them.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Why should an extension decide what my keyboard does?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  🎹 The invisible problem
&lt;/h3&gt;

&lt;p&gt;Keyboard shortcuts are muscle memory. They're personal. You build them over months and years of work, and they become part of how you think while coding.&lt;/p&gt;

&lt;p&gt;But VS Code treats extension shortcuts as equals to your own. They land in the same space, with the same priority, and they accumulate silently. The more extensions you install, the more your keyboard belongs to someone else's defaults.&lt;/p&gt;

&lt;p&gt;Most developers don't notice until something breaks. And by then, it's hard to know what changed, when, or why.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧩 Why I built Harmonia Shortcuts
&lt;/h3&gt;

&lt;p&gt;I wanted a simple answer to a simple question: &lt;strong&gt;which extension shortcuts am I actually using?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not a keybinding editor. Not a conflict resolver with complex rules. Just a way to see every shortcut that extensions added to my environment, and decide - one by one or in bulk - whether I want them active.&lt;/p&gt;

&lt;p&gt;That's what Harmonia Shortcuts does. It reads every extension's contributed keybindings, shows them grouped by extension, and lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Approve&lt;/strong&gt; the ones you want to keep.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deactivate&lt;/strong&gt; the ones that get in your way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Remap&lt;/strong&gt; the ones you like but want on a different key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Skip&lt;/strong&gt; the ones you'll decide about later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No automation. No heuristics. No "smart" decisions made on your behalf. Just you, your shortcuts, and a clear interface to review them.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔒 Your shortcuts are sacred
&lt;/h3&gt;

&lt;p&gt;Harmonia never touches your custom keybindings. They are read-only, always protected. The extension only manages what other extensions brought in - the shortcuts you never explicitly chose.&lt;/p&gt;

&lt;p&gt;If two extensions compete for the same key, Harmonia shows the conflict and lets you resolve it. If an extension updates and adds new shortcuts, you get a notification so nothing slips through unreviewed.&lt;/p&gt;

&lt;p&gt;Everything happens through &lt;code&gt;keybindings.json&lt;/code&gt; using standard VS Code mechanisms. No magic, no hidden state.&lt;/p&gt;




&lt;h3&gt;
  
  
  🐾 Built in good company
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FAgusRdz%2Fharmonia-shortcuts%2Frefs%2Fheads%2Fmaster%2Fimages%2Fhoney.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FAgusRdz%2Fharmonia-shortcuts%2Frefs%2Fheads%2Fmaster%2Fimages%2Fhoney.png" alt="Honey" width="408" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This project was built during long coding sessions with my dog Honey by my side - the best coding partner I could have asked for. He listened to every idea, stayed up for every late night, and kept me company through every line of code. Honey passed away, but his presence is part of everything in this project.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✳️ Where to Find It
&lt;/h3&gt;

&lt;p&gt;Harmonia Shortcuts is available now on the Visual Studio Code Marketplace.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=AgusRdz.harmonia-shortcuts" rel="noopener noreferrer"&gt;View on VS Code Marketplace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AgusRdz/harmonia-shortcuts" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ✳️ A governance tool, not a productivity hack
&lt;/h3&gt;

&lt;p&gt;Harmonia Shortcuts isn't about speed or optimization. It's about &lt;strong&gt;intention&lt;/strong&gt;. It's a small, honest tool that gives you back something VS Code doesn't provide out of the box: the ability to consciously decide which shortcuts should be active in your environment.&lt;/p&gt;




&lt;p&gt;The life has no shortcuts. But your editor should only have the ones you chose.&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>productivity</category>
      <category>developer</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Coding in Peace - The Story Behind Harmonia Zen</title>
      <dc:creator>Agustín Rodríguez</dc:creator>
      <pubDate>Sat, 31 Jan 2026 05:01:20 +0000</pubDate>
      <link>https://dev.to/agusrdz/coding-in-peace-the-story-behind-harmonia-zen-3370</link>
      <guid>https://dev.to/agusrdz/coding-in-peace-the-story-behind-harmonia-zen-3370</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;How the pursuit of distraction-free coding led me to build an extension that respects both your focus and your preferences.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Distraction Problem
&lt;/h3&gt;

&lt;p&gt;Every developer knows the feeling. You're deep in a complex problem, the logic is finally clicking into place, and then... a notification. A sidebar catches your eye. The minimap reminds you of that other bug you meant to fix. Your flow is broken.&lt;/p&gt;

&lt;p&gt;VS Code's built-in Zen Mode was supposed to solve this. Toggle it on, and the UI disappears. But I found myself frustrated by its all-or-nothing approach. Sometimes I need line numbers. Sometimes I want the minimap but not the sidebar. The binary choice felt limiting.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Control I Wanted
&lt;/h3&gt;

&lt;p&gt;I started keeping notes on my ideal setup for different tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Deep debugging&lt;/strong&gt;: Keep line numbers and gutter, hide everything else&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Writing documentation&lt;/strong&gt;: Minimal interface, but keep the scrollbar for navigation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quick edits&lt;/strong&gt;: Almost everything visible for context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long coding sessions&lt;/strong&gt;: Just the essentials, plus something to structure my time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last point led me to the Pomodoro Technique. I'd been using it for years with external timers, but context-switching to another app always felt like a small interruption in itself.&lt;/p&gt;

&lt;p&gt;What if my editor could handle both? A truly customizable Zen Mode, plus a built-in timer that understands the rhythm of focused work?&lt;/p&gt;




&lt;h3&gt;
  
  
  Building Harmonia Zen
&lt;/h3&gt;

&lt;p&gt;The core idea was simple: give developers granular control over their environment.&lt;/p&gt;

&lt;p&gt;Instead of one Zen Mode toggle, Harmonia Zen offers 17 individual controls:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Editor elements&lt;/strong&gt;: Line numbers, gutter, minimap, breadcrumbs, indent guides, bracket pairs, rulers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scrollbars&lt;/strong&gt;: Vertical and horizontal separately&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workbench&lt;/strong&gt;: Activity bar, status bar, sidebar, panel, tabs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behavior&lt;/strong&gt;: Cursor blinking, whitespace rendering, line highlighting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each one can be toggled independently. Your preferences are remembered. And when you exit Zen Mode, your original settings come back exactly as they were.&lt;/p&gt;




&lt;h3&gt;
  
  
  Preset Profiles
&lt;/h3&gt;

&lt;p&gt;But remembering 17 toggles for different scenarios? That's its own cognitive load.&lt;/p&gt;

&lt;p&gt;So I built presets:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Preset&lt;/th&gt;
&lt;th&gt;Philosophy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Minimal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Everything hidden. Pure text and thought.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Writer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Clean but navigable. Good for prose and documentation.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Focus&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Keep the coding aids (line numbers, indent guides), hide the distractions.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Custom&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Save your own configuration and recall it instantly.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Switch between them with a single click. No friction.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Pomodoro Integration
&lt;/h3&gt;

&lt;p&gt;The Pomodoro Technique structures work into focused intervals (traditionally 25 minutes), followed by short breaks (5 minutes), with longer breaks after several sessions.&lt;/p&gt;

&lt;p&gt;It's simple, but it works. The rhythm prevents burnout and keeps you aware of time passing.&lt;/p&gt;

&lt;p&gt;I built the timer directly into the extension:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Visual indicator&lt;/strong&gt; in the status bar showing time remaining&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Session tracking&lt;/strong&gt; so you know which interval you're on&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customizable durations&lt;/strong&gt; because 25 minutes isn't right for everyone&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-start option&lt;/strong&gt; for continuous flow without manual intervention&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The timer respects your focus. No intrusive popups—just a status bar update when your session ends.&lt;/p&gt;




&lt;h3&gt;
  
  
  Focus Statistics
&lt;/h3&gt;

&lt;p&gt;After using the timer for a while, I wanted to understand my patterns. When am I most productive? Am I consistent?&lt;/p&gt;

&lt;p&gt;Harmonia Zen tracks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Daily sessions and focus time&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Current streak and longest streak&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Weekly overview with visual charts&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;All-time cumulative statistics&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's not about gamification or pressure. It's about self-awareness. Some days I notice I've only completed two sessions—maybe it was a meeting-heavy day, or maybe I need to be more intentional tomorrow.&lt;/p&gt;

&lt;p&gt;All data is stored locally. No cloud sync, no analytics, no telemetry. Your productivity data stays yours.&lt;/p&gt;




&lt;h3&gt;
  
  
  What I Hope You Get From It
&lt;/h3&gt;

&lt;p&gt;If you've ever wished Zen Mode was more flexible, or if you've bounced between different Pomodoro apps looking for one that integrates with your workflow, Harmonia Zen might help.&lt;/p&gt;

&lt;p&gt;It's not about forcing a specific productivity system on you. It's about giving you the controls to create the environment that works for your brain.&lt;/p&gt;

&lt;p&gt;Some developers like minimal interfaces. Some need more context visible. Some thrive with strict time boundaries. Some prefer flowing without interruption. Harmonia Zen tries to accommodate all of these.&lt;/p&gt;




&lt;h3&gt;
  
  
  Privacy by Design
&lt;/h3&gt;

&lt;p&gt;Like all Harmonia extensions, privacy is non-negotiable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No telemetry or analytics&lt;/li&gt;
&lt;li&gt;No external communication&lt;/li&gt;
&lt;li&gt;All settings and statistics stored locally in VS Code&lt;/li&gt;
&lt;li&gt;Open source under MIT license&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your focus is yours. Your data is yours.&lt;/p&gt;




&lt;h3&gt;
  
  
  Where to Find It
&lt;/h3&gt;

&lt;p&gt;Harmonia Zen is available now on the Visual Studio Code Marketplace.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=AgusRdz.harmonia-zen" rel="noopener noreferrer"&gt;View on VS Code Marketplace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AgusRdz/harmonia-zen" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Thanks for Reading
&lt;/h3&gt;

&lt;p&gt;We spend countless hours in our code editors. Making that environment comfortable, focused, and personalized feels like time well invested.&lt;/p&gt;

&lt;p&gt;If you try Harmonia Zen, I'd love to hear how it fits into your workflow. What presets work for you? What Pomodoro durations feel right? Feedback helps shape future improvements.&lt;/p&gt;

&lt;p&gt;Code in peace.&lt;/p&gt;

&lt;p&gt;Cover image credit: &lt;a href="https://unsplash.com/photos/water-ripple-dOhJtfXJZfw" rel="noopener noreferrer"&gt;Levi XU&lt;/a&gt;, via &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>productivity</category>
      <category>pomodoro</category>
      <category>development</category>
    </item>
    <item>
      <title>From Glasses to Code - The Personal Journey Behind Harmonia Vision</title>
      <dc:creator>Agustín Rodríguez</dc:creator>
      <pubDate>Sun, 18 Jan 2026 22:36:51 +0000</pubDate>
      <link>https://dev.to/agusrdz/from-glasses-to-code-the-personal-journey-behind-harmonia-vision-1ofc</link>
      <guid>https://dev.to/agusrdz/from-glasses-to-code-the-personal-journey-behind-harmonia-vision-1ofc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;After almost a decade wearing glasses for myopia and astigmatism, I built an extension that finally understands what my eyes need.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Day Everything Changed
&lt;/h3&gt;

&lt;p&gt;It was mid-2016 when I first put on glasses. Myopia and astigmatism - two words that would become permanent companions in my life as a developer.&lt;/p&gt;

&lt;p&gt;I still remember that first moment of clarity. The world suddenly had edges again. Text on screens was crisp. But I also discovered something frustrating: the default settings in my code editor weren't designed with my eyes in mind.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Endless Tweaking
&lt;/h3&gt;

&lt;p&gt;Over the years, I developed a habit. Every time I set up a new machine or switched editors, I'd spend time adjusting font sizes, trying different fonts, playing with line heights. It was a ritual - sometimes taking hours to feel "right."&lt;/p&gt;

&lt;p&gt;But it was always guesswork. How big should the font be? Should I increase line spacing? Why does this font feel blurry even at larger sizes?&lt;/p&gt;

&lt;p&gt;I never had clear answers. Just trial and error, over and over.&lt;/p&gt;




&lt;h3&gt;
  
  
  From Harmonia Theme to Harmonia Vision
&lt;/h3&gt;

&lt;p&gt;When I built &lt;a href="https://agusrdz.dev/projects/harmonia" rel="noopener noreferrer"&gt;Harmonia Theme&lt;/a&gt;, my focus was on &lt;strong&gt;colors&lt;/strong&gt; - reducing visual noise, creating a calm palette that wouldn't strain my eyes during long sessions.&lt;/p&gt;

&lt;p&gt;But colors are only half the story.&lt;/p&gt;

&lt;p&gt;Typography matters just as much. For someone with astigmatism, letters that are too close together blur into each other. For someone with myopia, small text means constantly leaning toward the screen. And eye fatigue compounds everything.&lt;/p&gt;

&lt;p&gt;I realized I needed something more systematic. Something that understood the &lt;strong&gt;why&lt;/strong&gt; behind each adjustment, not just the &lt;strong&gt;what&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Understanding My Own Eyes
&lt;/h3&gt;

&lt;p&gt;I started researching how different vision conditions affect screen readability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Myopia&lt;/strong&gt; makes distant objects blurry - on a screen, this translates to needing larger text to maintain a comfortable viewing distance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Astigmatism&lt;/strong&gt; causes light to scatter irregularly, making closely-spaced characters blur together - increased letter spacing helps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eye fatigue&lt;/strong&gt; benefits from more vertical breathing room between lines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Light sensitivity&lt;/strong&gt; means high-contrast or heavy fonts can feel uncomfortable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each condition has its own needs. And when you have multiple conditions (like I do), they interact in complex ways.&lt;/p&gt;




&lt;h3&gt;
  
  
  Building the Calibrator
&lt;/h3&gt;

&lt;p&gt;Harmonia Vision started as a simple idea: what if my editor could understand my prescription?&lt;/p&gt;

&lt;p&gt;I built a calibration engine that considers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Which conditions you have&lt;/strong&gt; - select one or multiple from a list.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your actual prescription values&lt;/strong&gt; - sphere and cylinder, if you want precise recommendations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your current settings&lt;/strong&gt; - as a baseline that recommendations won't go below.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The engine uses empirically-derived thresholds based on real comfort profiles.&lt;/p&gt;

&lt;p&gt;When I ran the calibrator on my own setup, the results were eye-opening (pun intended). My manual settings after years of tweaking were:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;My Manual Config&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Font Size&lt;/td&gt;
&lt;td&gt;18px&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Line Height&lt;/td&gt;
&lt;td&gt;0 (auto)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Letter Spacing&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cursor Width&lt;/td&gt;
&lt;td&gt;1px&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The extension analyzed my conditions and recommended:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Recommendation&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Font Size&lt;/td&gt;
&lt;td&gt;19px&lt;/td&gt;
&lt;td&gt;Slightly larger for sustained comfort&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Line Height&lt;/td&gt;
&lt;td&gt;1.6&lt;/td&gt;
&lt;td&gt;Better line tracking with astigmatism&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Letter Spacing&lt;/td&gt;
&lt;td&gt;0.3px&lt;/td&gt;
&lt;td&gt;Reduces character blur from astigmatism&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cursor Width&lt;/td&gt;
&lt;td&gt;3px&lt;/td&gt;
&lt;td&gt;Easier to track with myopia&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The line height and letter spacing changes were things I'd never thought to adjust - but once I tried them, the difference was noticeable. Lines of code felt less cramped, and my eyes didn't have to work as hard to distinguish similar characters.&lt;/p&gt;

&lt;p&gt;It was validating to see the algorithm suggest improvements I didn't even know I needed.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Safe Apply Workflow
&lt;/h3&gt;

&lt;p&gt;One thing I learned from years of tweaking: sometimes you make a change and it looks great... until it doesn't. Maybe the font is too big for your monitor. Maybe the line height feels wrong after an hour of coding.&lt;/p&gt;

&lt;p&gt;So I built in a safety net:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automatic snapshots&lt;/strong&gt; of your settings before any change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Live preview&lt;/strong&gt; to test in real-time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One-click revert&lt;/strong&gt; to go back to your previous comfortable state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No more digging through settings to remember what values you had before. Just click "Revert" and you're back.&lt;/p&gt;




&lt;h3&gt;
  
  
  Privacy by Design
&lt;/h3&gt;

&lt;p&gt;Your prescription is personal medical information. I didn't want to build something that sent that data anywhere.&lt;/p&gt;

&lt;p&gt;Harmonia Vision is completely local:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No telemetry or analytics.&lt;/li&gt;
&lt;li&gt;Prescription values are used only for calculation, never stored permanently.&lt;/li&gt;
&lt;li&gt;All settings live in your VS Code configuration.&lt;/li&gt;
&lt;li&gt;The code is open source - you can verify every line.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  What I Hope You Get From It
&lt;/h3&gt;

&lt;p&gt;If you wear glasses, have eye strain, or just find yourself constantly tweaking editor settings - I built this for you.&lt;/p&gt;

&lt;p&gt;It's not a replacement for proper eye care. Please see your optometrist regularly.&lt;/p&gt;

&lt;p&gt;But it can help you find a starting point that actually considers your eyes, not just generic defaults designed for perfect vision.&lt;/p&gt;




&lt;h3&gt;
  
  
  A Decade Later
&lt;/h3&gt;

&lt;p&gt;Almost ten years with glasses now. My prescription has changed a few times. My monitors have changed. My preferred themes have changed.&lt;/p&gt;

&lt;p&gt;But the fundamental challenge remains: making text on screens comfortable for eyes that need a little help.&lt;/p&gt;

&lt;p&gt;Harmonia Vision is my answer to that challenge. A small tool that applies what I've learned from years of adjusting, researching, and understanding my own vision.&lt;/p&gt;

&lt;p&gt;I hope it helps your eyes as much as it helps mine.&lt;/p&gt;




&lt;h3&gt;
  
  
  Where to Find It
&lt;/h3&gt;

&lt;p&gt;Harmonia Vision is available now on the Visual Studio Code Marketplace.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=AgusRdz.harmonia-vision" rel="noopener noreferrer"&gt;View on VS Code Marketplace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/AgusRdz/harmonia-vision" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://agusrdz.dev/projects/harmonia" rel="noopener noreferrer"&gt;Project Page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Thanks for Reading
&lt;/h3&gt;

&lt;p&gt;Building developer tools that focus on accessibility and comfort feels meaningful to me. We spend so many hours looking at code - it should be as comfortable as possible.&lt;/p&gt;

&lt;p&gt;If you try Harmonia Vision, I'd love to hear how it works for you. Especially if you have different vision conditions than mine - your feedback helps make it better for everyone.&lt;/p&gt;

&lt;p&gt;Take care of your eyes.&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>a11y</category>
      <category>sideprojects</category>
      <category>extensions</category>
    </item>
    <item>
      <title>Refactor Smart Today, Move Faster Tomorrow — Bonus Pack: 4 Lessons to Refactor Smarter</title>
      <dc:creator>Agustín Rodríguez</dc:creator>
      <pubDate>Mon, 06 Oct 2025 18:29:58 +0000</pubDate>
      <link>https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-bonus-pack-4-lessons-to-refactor-smarter-2jpb</link>
      <guid>https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-bonus-pack-4-lessons-to-refactor-smarter-2jpb</guid>
      <description>&lt;h2&gt;
  
  
  Extra insights that make your refactors more strategic, collaborative, and sustainable
&lt;/h2&gt;




&lt;p&gt;This Bonus Pack expands on everything we've covered so far with &lt;strong&gt;4 focused lessons&lt;/strong&gt; that address the &lt;em&gt;people&lt;/em&gt;, &lt;em&gt;process&lt;/em&gt;, and &lt;em&gt;real-world constraints&lt;/em&gt; around refactoring.&lt;/p&gt;

&lt;p&gt;Let's dive in.&lt;/p&gt;




&lt;h2&gt;
  
  
  🆕 Bonus 1 — When You Should Rewrite Instead of Refactor
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Knowing when to let go and start over
&lt;/h3&gt;

&lt;p&gt;Not every system deserves a refactor.&lt;br&gt;&lt;br&gt;
Sometimes the best move is to rebuild from scratch - but that decision should never be impulsive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Red flags that suggest a rewrite is better:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No tests, no docs, nobody understands the code
&lt;/li&gt;
&lt;li&gt;Tech stack is outdated or unsupported
&lt;/li&gt;
&lt;li&gt;Bugs are symptoms of flawed architecture
&lt;/li&gt;
&lt;li&gt;Every change introduces 3 new bugs
&lt;/li&gt;
&lt;li&gt;You've already tried refactoring and failed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How to approach a rewrite responsibly:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep the &lt;strong&gt;business logic contract&lt;/strong&gt; consistent
&lt;/li&gt;
&lt;li&gt;Build the new system &lt;em&gt;next to&lt;/em&gt; the old one
&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;feature flags&lt;/strong&gt; or routing to slowly switch traffic
&lt;/li&gt;
&lt;li&gt;Mirror real data to test before cutting over
&lt;/li&gt;
&lt;li&gt;Remove the legacy system only when the new one is fully trusted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 Rewrites should be &lt;strong&gt;strategic&lt;/strong&gt;, not emotional.&lt;/p&gt;




&lt;h2&gt;
  
  
  🆕 Bonus 2 — Refactoring in Teams
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How to avoid stepping on each other and make the work collaborative
&lt;/h3&gt;

&lt;p&gt;Refactoring as a team requires more than just splitting up files. You need shared direction, boundaries, and communication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips to make it smooth:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define &lt;em&gt;clear scope and goals&lt;/em&gt; before anyone starts coding
&lt;/li&gt;
&lt;li&gt;Break work by &lt;strong&gt;responsibility&lt;/strong&gt;, not line numbers
&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;contracts or interfaces&lt;/strong&gt; to reduce coupling between teammates' work
&lt;/li&gt;
&lt;li&gt;Set up PR templates to explain each change
&lt;/li&gt;
&lt;li&gt;Do a midpoint check-in before it's too late to adjust&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Optional extras:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a shared kanban/board to track atomic refactor tasks
&lt;/li&gt;
&lt;li&gt;Write down agreed rules: naming, file structure, error handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧠 Don't just refactor code — refactor your collaboration.&lt;/p&gt;




&lt;h2&gt;
  
  
  🆕 Bonus 3 — The Printable Refactor Checklist
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A step-by-step guide you can print or paste into Notion
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pre-Refactor&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Do we have a clear &lt;em&gt;why&lt;/em&gt;?
&lt;/li&gt;
&lt;li&gt;[ ] Are the goals measurable?
&lt;/li&gt;
&lt;li&gt;[ ] Are there existing tests or metrics?
&lt;/li&gt;
&lt;li&gt;[ ] Are stakeholders aware or involved?
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Planning&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Scope is defined
&lt;/li&gt;
&lt;li&gt;[ ] Strategy chosen (incremental, strangler, etc.)
&lt;/li&gt;
&lt;li&gt;[ ] Tools (CI, linters, test runners) are in place
&lt;/li&gt;
&lt;li&gt;[ ] Any risky parts flagged?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Execution&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Each commit is purposeful
&lt;/li&gt;
&lt;li&gt;[ ] No behavior changed without reason
&lt;/li&gt;
&lt;li&gt;[ ] Tests updated along the way
&lt;/li&gt;
&lt;li&gt;[ ] Team is aware of changes in flow or interfaces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Aftermath&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Cleanup done (flags, dead code, mocks)
&lt;/li&gt;
&lt;li&gt;[ ] Metrics re-evaluated
&lt;/li&gt;
&lt;li&gt;[ ] Docs updated
&lt;/li&gt;
&lt;li&gt;[ ] Lessons shared with the team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ Use this before &lt;em&gt;every&lt;/em&gt; refactor.&lt;/p&gt;




&lt;h2&gt;
  
  
  🆕 Bonus 4 — Handling Pushback From Stakeholders
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How to talk about refactors without sounding like a code snob
&lt;/h3&gt;

&lt;p&gt;Refactors are often hard to "sell" to leadership or PMs. Here's how to translate value into their language.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Developer Speak&lt;/th&gt;
&lt;th&gt;Stakeholder Language&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"This code is unmaintainable"&lt;/td&gt;
&lt;td&gt;"This slows down our delivery"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"We need to decouple this"&lt;/td&gt;
&lt;td&gt;"This change is risky and expensive as-is"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"No tests, can't touch it"&lt;/td&gt;
&lt;td&gt;"Without safety checks, we risk regressions"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Common objections:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❌ “Why fix something that works?”&lt;br&gt;&lt;br&gt;
✔️ “Because it's fragile, expensive, and slowing down progress.”&lt;/p&gt;

&lt;p&gt;❌ “Won't this delay our release?”&lt;br&gt;&lt;br&gt;
✔️ “It's short-term cost for long-term speed and fewer bugs.”&lt;/p&gt;

&lt;p&gt;❌ “Let's just patch it again.”&lt;br&gt;&lt;br&gt;
✔️ “Patches accumulate tech debt — we need a long-term fix.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Refactoring is part of software health. Don't wait for things to break.&lt;/p&gt;




&lt;h2&gt;
  
  
  📌 Final Note: Refactoring Is a Head Start, Not a Free Ride
&lt;/h2&gt;

&lt;p&gt;Refactoring doesn't eliminate maintenance — it just makes it &lt;em&gt;manageable&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A cleaner foundation
&lt;/li&gt;
&lt;li&gt;Easier testing
&lt;/li&gt;
&lt;li&gt;Better boundaries
&lt;/li&gt;
&lt;li&gt;More confident teams&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it doesn't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Freeze time
&lt;/li&gt;
&lt;li&gt;Prevent technical debt forever
&lt;/li&gt;
&lt;li&gt;Exempt you from good practices
&lt;/li&gt;
&lt;li&gt;Replace the need to update dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;🧠 Refactor smart today. Maintain smarter tomorrow.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  📚 Series Index — &lt;em&gt;Refactor Smart Today, Move Faster Tomorrow&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;A practical guide to refactoring without fear — from planning to validation.&lt;/p&gt;

&lt;p&gt;1️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-1-before-you-touch-a-line-of-code-3557"&gt;Before You Touch a Line of Code&lt;/a&gt;&lt;br&gt;&lt;br&gt;
2️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-2-plan-your-refactor-step-by-step-1021"&gt;Plan Your Refactor Step by Step&lt;/a&gt;&lt;br&gt;&lt;br&gt;
3️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-3-tools-that-save-you-from-yourself-mnj"&gt;Tools That Save You From Yourself&lt;/a&gt;&lt;br&gt;&lt;br&gt;
4️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-4-refactoring-without-regret-26bl"&gt;Refactoring Without Regret&lt;/a&gt;&lt;br&gt;&lt;br&gt;
5️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-5-after-the-refactor-how-to-know-it-worked-47km"&gt;After the Refactor: How to Know It Worked&lt;/a&gt;&lt;br&gt;&lt;br&gt;
✨ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-bonus-pack-4-lessons-to-refactor-smarter-2jpb"&gt;Bonus: 4 Lessons to Refactor Smarter (Not Harder)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cover image credit: &lt;a href="https://unsplash.com/photos/turned-on-gray-laptop-computer-XJXWbfSo2f0" rel="noopener noreferrer"&gt;Luca Bravo&lt;/a&gt;, via &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>softwaredevelopment</category>
      <category>leadership</category>
      <category>development</category>
    </item>
    <item>
      <title>Refactor Smart Today, Move Faster Tomorrow — Part 5: After the Refactor: How to Know It Worked</title>
      <dc:creator>Agustín Rodríguez</dc:creator>
      <pubDate>Tue, 23 Sep 2025 18:43:21 +0000</pubDate>
      <link>https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-5-after-the-refactor-how-to-know-it-worked-47km</link>
      <guid>https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-5-after-the-refactor-how-to-know-it-worked-47km</guid>
      <description>&lt;h2&gt;
  
  
  Validation, Cleanup, and Wrapping Things Up Properly
&lt;/h2&gt;




&lt;p&gt;You made it. The refactor is merged.&lt;br&gt;&lt;br&gt;
You didn't break production (hopefully).&lt;br&gt;&lt;br&gt;
Now what?&lt;/p&gt;

&lt;p&gt;A refactor isn't truly done when the code is merged — it's done when you've validated its impact, cleaned up the mess, and learned from the process.&lt;/p&gt;

&lt;p&gt;Let's go over what happens &lt;em&gt;after&lt;/em&gt; the refactor.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ Validate That You Actually Improved Something
&lt;/h3&gt;

&lt;p&gt;Compare your "before" and "after" metrics:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Before&lt;/th&gt;
&lt;th&gt;After&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Test coverage&lt;/td&gt;
&lt;td&gt;58%&lt;/td&gt;
&lt;td&gt;85%&lt;/td&gt;
&lt;td&gt;✅ Improvement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Average response time&lt;/td&gt;
&lt;td&gt;600ms&lt;/td&gt;
&lt;td&gt;320ms&lt;/td&gt;
&lt;td&gt;✅ Faster&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cyclomatic complexity&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;✅ Cleaner logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bug reports/week&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;✅ More stable&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If the results don't show improvement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Re-evaluate the refactor goals
&lt;/li&gt;
&lt;li&gt;Check if you optimized the wrong thing
&lt;/li&gt;
&lt;li&gt;Or consider follow-up iterations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 Don't assume success — &lt;strong&gt;measure it&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔍 Re-Test Everything One More Time
&lt;/h3&gt;

&lt;p&gt;Now that it's in production or merged into main:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run full test suites
&lt;/li&gt;
&lt;li&gt;Double-check edge cases
&lt;/li&gt;
&lt;li&gt;Monitor for logs, errors, anomalies
&lt;/li&gt;
&lt;li&gt;Verify integrations with other services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optional: &lt;strong&gt;QA smoke tests&lt;/strong&gt; or exploratory testing in staging environments.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧹 Clean Up Technical Debris
&lt;/h3&gt;

&lt;p&gt;During your refactor, you may have left behind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feature flags that are no longer needed
&lt;/li&gt;
&lt;li&gt;Deprecated functions
&lt;/li&gt;
&lt;li&gt;Temporary mocks or shims
&lt;/li&gt;
&lt;li&gt;Old config variables
&lt;/li&gt;
&lt;li&gt;Duplicated code (old + new logic)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now's the time to &lt;strong&gt;remove the scaffolding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;💡 You built it safely — now you make it clean.&lt;/p&gt;




&lt;h3&gt;
  
  
  📚 Update Documentation
&lt;/h3&gt;

&lt;p&gt;If your refactor introduced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New public interfaces
&lt;/li&gt;
&lt;li&gt;New architectural conventions
&lt;/li&gt;
&lt;li&gt;Changed behavior (even subtle)
&lt;/li&gt;
&lt;li&gt;New environment/config requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...then update:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;README files
&lt;/li&gt;
&lt;li&gt;Wiki pages or Confluence
&lt;/li&gt;
&lt;li&gt;Internal dev docs
&lt;/li&gt;
&lt;li&gt;Diagrams (if relevant)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧠 Future-you (or your teammates) will thank you.&lt;/p&gt;




&lt;h3&gt;
  
  
  📣 Share Learnings With the Team
&lt;/h3&gt;

&lt;p&gt;Whether your refactor was a solo mission or a team effort:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do a quick retro or post-mortem
&lt;/li&gt;
&lt;li&gt;Share what worked (patterns, tools, strategies)
&lt;/li&gt;
&lt;li&gt;Document pitfalls or challenges
&lt;/li&gt;
&lt;li&gt;Leave suggestions for next time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💬 "Here's how I handled the legacy service and rolled it out safely" is gold for onboarding and reuse.&lt;/p&gt;




&lt;h3&gt;
  
  
  📦 Optional: Leave a Changelog or Migration Note
&lt;/h3&gt;

&lt;p&gt;If your changes affect how others use the codebase, leave a &lt;strong&gt;clear, focused changelog&lt;/strong&gt; with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What changed
&lt;/li&gt;
&lt;li&gt;Why it changed
&lt;/li&gt;
&lt;li&gt;What to update
&lt;/li&gt;
&lt;li&gt;Any deprecated methods or structures
&lt;/li&gt;
&lt;li&gt;Links to examples or diffs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even if it's just a comment in a PR or GitHub release notes, it saves a ton of time later.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧠 Final Thought
&lt;/h3&gt;

&lt;p&gt;A great refactor doesn't just clean code — it leaves the entire system &lt;strong&gt;healthier&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster
&lt;/li&gt;
&lt;li&gt;More stable
&lt;/li&gt;
&lt;li&gt;Easier to understand
&lt;/li&gt;
&lt;li&gt;Easier to extend
&lt;/li&gt;
&lt;li&gt;Safer to maintain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you can say that about your project after a refactor, &lt;strong&gt;you did it right&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  📚 Series Index — &lt;em&gt;Refactor Smart Today, Move Faster Tomorrow&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;A practical guide to refactoring without fear — from planning to validation.&lt;/p&gt;

&lt;p&gt;1️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-1-before-you-touch-a-line-of-code-3557"&gt;Before You Touch a Line of Code&lt;/a&gt;&lt;br&gt;&lt;br&gt;
2️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-2-plan-your-refactor-step-by-step-1021"&gt;Plan Your Refactor Step by Step&lt;/a&gt;&lt;br&gt;&lt;br&gt;
3️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-3-tools-that-save-you-from-yourself-mnj"&gt;Tools That Save You From Yourself&lt;/a&gt;&lt;br&gt;&lt;br&gt;
4️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-4-refactoring-without-regret-26bl"&gt;Refactoring Without Regret&lt;/a&gt;&lt;br&gt;&lt;br&gt;
5️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-5-after-the-refactor-how-to-know-it-worked-47km"&gt;After the Refactor: How to Know It Worked&lt;/a&gt;&lt;br&gt;&lt;br&gt;
✨ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-bonus-pack-4-lessons-to-refactor-smarter-2jpb"&gt;Bonus: 4 Lessons to Refactor Smarter (Not Harder)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cover image credit: &lt;a href="https://unsplash.com/photos/turned-on-macbook-pro-wit-programming-codes-display-f77Bh3inUpE" rel="noopener noreferrer"&gt;Arnold Francisca&lt;/a&gt;, via &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>analytics</category>
      <category>cleancode</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Refactor Smart Today, Move Faster Tomorrow — Part 4: Refactoring Without Regret</title>
      <dc:creator>Agustín Rodríguez</dc:creator>
      <pubDate>Tue, 16 Sep 2025 17:38:34 +0000</pubDate>
      <link>https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-4-refactoring-without-regret-26bl</link>
      <guid>https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-4-refactoring-without-regret-26bl</guid>
      <description>&lt;p&gt;So you've got a plan, you've got tools, and you're ready to refactor.&lt;br&gt;&lt;br&gt;
This is where good intentions often go sideways.&lt;/p&gt;

&lt;p&gt;Let's make sure your refactor doesn't turn into a rewrite you'll regret.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ Best Practices While Refactoring
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Keep the System Green at All Times&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Never let your tests stay red for too long. Every change should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep the app working
&lt;/li&gt;
&lt;li&gt;Keep the test suite passing
&lt;/li&gt;
&lt;li&gt;Leave the code in a better state than before&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 &lt;em&gt;Broken code for more than a day = trouble ahead.&lt;/em&gt;&lt;/p&gt;




&lt;h4&gt;
  
  
  2. &lt;strong&gt;Small, Purposeful Commits&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Break your refactor into &lt;strong&gt;atomic commits&lt;/strong&gt;, each one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Solves one thing
&lt;/li&gt;
&lt;li&gt;Is easy to understand
&lt;/li&gt;
&lt;li&gt;Is easy to revert&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Bonus: Reviewing or debugging later becomes 10x easier.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h4&gt;
  
  
  3. &lt;strong&gt;Do Not Change Behavior Unless You Have To&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Refactoring ≠ rewriting features. If the output or behavior changes, you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A reason
&lt;/li&gt;
&lt;li&gt;A test
&lt;/li&gt;
&lt;li&gt;A migration plan (if applicable)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔍 The goal is to &lt;strong&gt;improve structure, not functionality&lt;/strong&gt; — unless the behavior was already wrong.&lt;/p&gt;




&lt;h4&gt;
  
  
  4. &lt;strong&gt;Add Tests Before You Touch Untested Code&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;If you're about to refactor a method with zero tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write tests first
&lt;/li&gt;
&lt;li&gt;Validate existing behavior
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Then&lt;/em&gt; refactor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This way, you'll catch regressions instantly — and build trust in your changes.&lt;/p&gt;




&lt;h4&gt;
  
  
  5. &lt;strong&gt;Rename Things Intelligently&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;A good refactor often involves &lt;strong&gt;better naming&lt;/strong&gt; — but don't get carried away.&lt;/p&gt;

&lt;p&gt;Tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rename only when it adds clarity
&lt;/li&gt;
&lt;li&gt;Avoid generic renames like &lt;code&gt;Helper&lt;/code&gt; or &lt;code&gt;Manager&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Prefer domain language: &lt;code&gt;DonationProcessor&lt;/code&gt; &amp;gt; &lt;code&gt;ServiceHandler&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Clear names are half the battle.&lt;/p&gt;




&lt;h4&gt;
  
  
  6. &lt;strong&gt;Make Invisible Progress&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The best refactors go unnoticed by the end user.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No regressions
&lt;/li&gt;
&lt;li&gt;No broken flows
&lt;/li&gt;
&lt;li&gt;No "wait, why is this acting weird now?"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You &lt;em&gt;can&lt;/em&gt; celebrate your refactor, but your product team shouldn't have to know it happened.&lt;/p&gt;




&lt;h4&gt;
  
  
  7. &lt;strong&gt;Document Complex Transitions&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Some refactors introduce patterns, abstractions, or architectural shifts.&lt;br&gt;&lt;br&gt;
Leave &lt;strong&gt;breadcrumbs&lt;/strong&gt; for future devs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inline comments (brief and useful)
&lt;/li&gt;
&lt;li&gt;Code examples in the README
&lt;/li&gt;
&lt;li&gt;GitHub issues or ADRs (Architecture Decision Records)
&lt;/li&gt;
&lt;li&gt;Migration guides (for APIs, configs, etc.)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🚨 Common Mistakes That Break Refactors
&lt;/h3&gt;

&lt;h4&gt;
  
  
  ❌ 1. Refactoring Without Tests
&lt;/h4&gt;

&lt;p&gt;You're walking blind. One wrong move and it's over.&lt;/p&gt;

&lt;h4&gt;
  
  
  ❌ 2. Changing Everything at Once
&lt;/h4&gt;

&lt;p&gt;This often leads to huge PRs that are impossible to review or roll back.&lt;/p&gt;

&lt;h4&gt;
  
  
  ❌ 3. Focusing on Perfection
&lt;/h4&gt;

&lt;p&gt;Perfect is the enemy of done. Refactor to &lt;strong&gt;improve&lt;/strong&gt;, not to create utopia.&lt;/p&gt;

&lt;h4&gt;
  
  
  ❌ 4. Forgetting to Communicate
&lt;/h4&gt;

&lt;p&gt;If the team isn't aligned, your "clean code" might break their work.&lt;/p&gt;

&lt;h4&gt;
  
  
  ❌ 5. Deleting Legacy Code Prematurely
&lt;/h4&gt;

&lt;p&gt;Don't rip out old logic &lt;em&gt;until the new one is 100% verified&lt;/em&gt; (and ideally, toggled off safely).&lt;/p&gt;




&lt;h3&gt;
  
  
  🧘‍♂️ Optional but Powerful: Use Feature Branches + PR Templates
&lt;/h3&gt;

&lt;p&gt;Structure your PRs to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reviewable in &amp;lt;15 mins
&lt;/li&gt;
&lt;li&gt;Linked to clear goals ("This PR isolates email logic from controller")
&lt;/li&gt;
&lt;li&gt;Labeled by type (&lt;code&gt;refactor&lt;/code&gt;, &lt;code&gt;chore&lt;/code&gt;, &lt;code&gt;migration&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This avoids misunderstandings and makes your changes traceable.&lt;/p&gt;




&lt;h3&gt;
  
  
  📌 Summary
&lt;/h3&gt;

&lt;p&gt;Refactoring isn't just about moving code — it's about moving &lt;strong&gt;with intention&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
Keep these in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stay green (tests passing)
&lt;/li&gt;
&lt;li&gt;Work in small steps
&lt;/li&gt;
&lt;li&gt;Avoid changing behavior unless needed
&lt;/li&gt;
&lt;li&gt;Cover everything with tests
&lt;/li&gt;
&lt;li&gt;Communicate with the team
&lt;/li&gt;
&lt;li&gt;Celebrate clarity, not cleverness&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📚 Series Index — &lt;em&gt;Refactor Smart Today, Move Faster Tomorrow&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;A practical guide to refactoring without fear — from planning to validation.&lt;/p&gt;

&lt;p&gt;1️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-1-before-you-touch-a-line-of-code-3557"&gt;Before You Touch a Line of Code&lt;/a&gt;&lt;br&gt;&lt;br&gt;
2️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-2-plan-your-refactor-step-by-step-1021"&gt;Plan Your Refactor Step by Step&lt;/a&gt;&lt;br&gt;&lt;br&gt;
3️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-3-tools-that-save-you-from-yourself-mnj"&gt;Tools That Save You From Yourself&lt;/a&gt;&lt;br&gt;&lt;br&gt;
4️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-4-refactoring-without-regret-26bl"&gt;Refactoring Without Regret&lt;/a&gt;&lt;br&gt;&lt;br&gt;
5️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-5-after-the-refactor-how-to-know-it-worked-47km"&gt;After the Refactor: How to Know It Worked&lt;/a&gt;&lt;br&gt;&lt;br&gt;
✨ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-bonus-pack-4-lessons-to-refactor-smarter-2jpb"&gt;Bonus: 4 Lessons to Refactor Smarter (Not Harder)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cover image credit: &lt;a href="https://unsplash.com/photos/black-flat-screen-computer-monitor-oXlXu2qukGE" rel="noopener noreferrer"&gt;Mohammad Rahmani&lt;/a&gt;, via &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>cleancode</category>
      <category>softwaredevelopment</category>
      <category>development</category>
    </item>
    <item>
      <title>Refactor Smart Today, Move Faster Tomorrow — Part 3: Tools That Save You From Yourself</title>
      <dc:creator>Agustín Rodríguez</dc:creator>
      <pubDate>Tue, 09 Sep 2025 17:47:01 +0000</pubDate>
      <link>https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-3-tools-that-save-you-from-yourself-mnj</link>
      <guid>https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-3-tools-that-save-you-from-yourself-mnj</guid>
      <description>&lt;p&gt;Refactoring without tooling is like free climbing without a harness.&lt;br&gt;&lt;br&gt;
Yes, you &lt;em&gt;can&lt;/em&gt; do it, but the chances of disaster increase with every step.&lt;/p&gt;

&lt;p&gt;This part focuses on the &lt;strong&gt;tools&lt;/strong&gt; that help you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Catch mistakes early
&lt;/li&gt;
&lt;li&gt;Keep your code consistent
&lt;/li&gt;
&lt;li&gt;Detect broken logic or structure
&lt;/li&gt;
&lt;li&gt;Measure test coverage
&lt;/li&gt;
&lt;li&gt;Validate your progress continuously&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's break it down by category.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧹 Linters and Formatters: Keep it Clean, Automatically
&lt;/h3&gt;

&lt;p&gt;Before you touch anything, set up tools that &lt;strong&gt;enforce style and catch basic issues&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Examples:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PHP&lt;/strong&gt;: &lt;code&gt;php-cs-fixer&lt;/code&gt;, &lt;code&gt;PHP_CodeSniffer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript/TypeScript&lt;/strong&gt;: &lt;code&gt;ESLint&lt;/code&gt;, &lt;code&gt;Prettier&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt;: &lt;code&gt;black&lt;/code&gt;, &lt;code&gt;flake8&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 Linters catch stuff like unused variables, bad formatting, unreachable code, etc.&lt;/p&gt;

&lt;p&gt;Why it matters:&lt;br&gt;&lt;br&gt;
👉 They prevent you from reviewing whitespace in PRs and keep codebase consistent &lt;em&gt;even if you refactor 20 files&lt;/em&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧠 Static Analysis: See Problems Before They Happen
&lt;/h3&gt;

&lt;p&gt;Static analyzers inspect your code &lt;em&gt;without running it&lt;/em&gt;. They're great at finding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type mismatches
&lt;/li&gt;
&lt;li&gt;Unreachable code
&lt;/li&gt;
&lt;li&gt;Bad inheritance
&lt;/li&gt;
&lt;li&gt;Deprecated functions
&lt;/li&gt;
&lt;li&gt;Dangerous constructs&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Examples:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PHP&lt;/strong&gt;: &lt;code&gt;PHPStan&lt;/code&gt;, &lt;code&gt;Psalm&lt;/code&gt;, &lt;code&gt;Rector&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JS/TS&lt;/strong&gt;: &lt;code&gt;tsc --noEmit&lt;/code&gt;, &lt;code&gt;SonarLint&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt;: &lt;code&gt;mypy&lt;/code&gt;, &lt;code&gt;pylint&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why it matters:&lt;br&gt;&lt;br&gt;
👉 They give you an &lt;strong&gt;early warning system&lt;/strong&gt; for logical bugs &lt;em&gt;before&lt;/em&gt; runtime.&lt;/p&gt;




&lt;h3&gt;
  
  
  📏 Metrics and Quality: Understand Your Code's Shape
&lt;/h3&gt;

&lt;p&gt;You can't improve what you don't measure. Tools like these give insight into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complexity per function/class
&lt;/li&gt;
&lt;li&gt;Code duplication
&lt;/li&gt;
&lt;li&gt;Coupling between modules
&lt;/li&gt;
&lt;li&gt;Files with too many responsibilities&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Examples:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PHP&lt;/strong&gt;: &lt;code&gt;PHP Metrics&lt;/code&gt;, &lt;code&gt;PHP Insights&lt;/code&gt;, &lt;code&gt;PHP Mess Detector&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JS&lt;/strong&gt;: &lt;code&gt;complexity-report&lt;/code&gt;, &lt;code&gt;plato&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI plugins&lt;/strong&gt;: &lt;code&gt;Code Climate&lt;/code&gt;, &lt;code&gt;SonarQube&lt;/code&gt;, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why it matters:&lt;br&gt;&lt;br&gt;
👉 Use them to &lt;strong&gt;prioritize your refactor targets&lt;/strong&gt; — focus on the worst offenders first.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧪 Tests and Coverage: Your Safety Net
&lt;/h3&gt;

&lt;p&gt;No test, no refactor. Period.&lt;/p&gt;

&lt;p&gt;Tests make sure your changes didn't break anything that used to work. They also help you &lt;strong&gt;refactor fearlessly&lt;/strong&gt; — which is the entire point.&lt;/p&gt;

&lt;p&gt;Make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Unit tests&lt;/strong&gt;: Fast, focused, per module
&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Integration tests&lt;/strong&gt;: Do modules talk to each other correctly?
&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Regression tests&lt;/strong&gt;: Does the system still behave the same?
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use &lt;strong&gt;coverage tools&lt;/strong&gt; to guide your testing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PHP&lt;/strong&gt;: &lt;code&gt;Xdebug + PHPUnit&lt;/code&gt;, &lt;code&gt;Infection&lt;/code&gt; (mutation testing)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JS&lt;/strong&gt;: &lt;code&gt;Jest --coverage&lt;/code&gt;, &lt;code&gt;vitest&lt;/code&gt;, &lt;code&gt;cypress&lt;/code&gt; for E2E
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt;: &lt;code&gt;coverage.py&lt;/code&gt;, &lt;code&gt;pytest&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why it matters:&lt;br&gt;&lt;br&gt;
👉 If a module has no tests and you refactor it, you're flying blind.&lt;/p&gt;




&lt;h3&gt;
  
  
  🚦 Continuous Integration: Automate the Checks
&lt;/h3&gt;

&lt;p&gt;A good CI setup runs your tests, linters, and checks on every push or PR.&lt;br&gt;&lt;br&gt;
This is your second parachute.&lt;/p&gt;

&lt;h4&gt;
  
  
  Useful CI/CD tools:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Actions
&lt;/li&gt;
&lt;li&gt;GitLab CI
&lt;/li&gt;
&lt;li&gt;CircleCI
&lt;/li&gt;
&lt;li&gt;Jenkins
&lt;/li&gt;
&lt;li&gt;Bitbucket Pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good pipeline should include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Linting
&lt;/li&gt;
&lt;li&gt;✅ Static analysis
&lt;/li&gt;
&lt;li&gt;✅ Tests
&lt;/li&gt;
&lt;li&gt;✅ Build (if applicable)
&lt;/li&gt;
&lt;li&gt;✅ Optional: visual diff, deploy preview, DB migration dry-run, etc.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  🧯 Feature Flags (Optional but Life-Saving)
&lt;/h3&gt;

&lt;p&gt;If your refactor affects live code paths, a feature flag system allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deploy the code but &lt;strong&gt;disable it in production&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Roll out to specific environments or users
&lt;/li&gt;
&lt;li&gt;Toggle back instantly if something goes wrong&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Tools:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;LaunchDarkly&lt;/code&gt;, &lt;code&gt;Unleash&lt;/code&gt;, &lt;code&gt;ConfigCat&lt;/code&gt;, or custom boolean flags in code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why it matters:&lt;br&gt;&lt;br&gt;
👉 Gives you &lt;strong&gt;rollback safety&lt;/strong&gt; without a full deploy.&lt;/p&gt;




&lt;h3&gt;
  
  
  📌 Suggested Tooling Stack Example (for a PHP+React project)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Area&lt;/th&gt;
&lt;th&gt;Tool(s)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Linting (PHP)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;php-cs-fixer&lt;/code&gt;, &lt;code&gt;PHP_CodeSniffer&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linting (JS)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;ESLint&lt;/code&gt;, &lt;code&gt;Prettier&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Static analysis&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PHPStan&lt;/code&gt;, &lt;code&gt;tsc&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test runner&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PHPUnit&lt;/code&gt;, &lt;code&gt;Jest&lt;/code&gt;, &lt;code&gt;React Testing Library&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coverage&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Xdebug&lt;/code&gt;, &lt;code&gt;jest --coverage&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quality metrics&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PHP Insights&lt;/code&gt;, &lt;code&gt;SonarQube&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI/CD&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;GitHub Actions&lt;/code&gt; or similar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Feature toggles&lt;/td&gt;
&lt;td&gt;Custom flags or service-based&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  ✅ Takeaway
&lt;/h3&gt;

&lt;p&gt;The right tools don't slow you down — they &lt;strong&gt;give you the confidence&lt;/strong&gt; to go fast without breaking things.&lt;/p&gt;

&lt;p&gt;Before you dive into your next refactor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automate what you can
&lt;/li&gt;
&lt;li&gt;Catch issues early
&lt;/li&gt;
&lt;li&gt;Make testing easy and visible
&lt;/li&gt;
&lt;li&gt;Let CI/CD do the boring stuff
&lt;/li&gt;
&lt;li&gt;Use tools to guide, not replace, your decisions&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📚 Series Index — &lt;em&gt;Refactor Smart Today, Move Faster Tomorrow&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;A practical guide to refactoring without fear — from planning to validation.&lt;/p&gt;

&lt;p&gt;1️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-1-before-you-touch-a-line-of-code-3557"&gt;Before You Touch a Line of Code&lt;/a&gt;&lt;br&gt;&lt;br&gt;
2️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-2-plan-your-refactor-step-by-step-1021"&gt;Plan Your Refactor Step by Step&lt;/a&gt;&lt;br&gt;&lt;br&gt;
3️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-3-tools-that-save-you-from-yourself-mnj"&gt;Tools That Save You From Yourself&lt;/a&gt;&lt;br&gt;&lt;br&gt;
4️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-4-refactoring-without-regret-26bl"&gt;Refactoring Without Regret&lt;/a&gt;&lt;br&gt;&lt;br&gt;
5️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-5-after-the-refactor-how-to-know-it-worked-47km"&gt;After the Refactor: How to Know It Worked&lt;/a&gt;&lt;br&gt;&lt;br&gt;
✨ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-bonus-pack-4-lessons-to-refactor-smarter-2jpb"&gt;Bonus: 4 Lessons to Refactor Smarter (Not Harder)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cover image credit: &lt;a href="https://unsplash.com/photos/black-flat-screen-computer-monitor-8qEB0fTe9Vw" rel="noopener noreferrer"&gt;Pankaj Patel&lt;/a&gt;, via &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>softwaredevelopment</category>
      <category>cleancode</category>
      <category>development</category>
    </item>
    <item>
      <title>Refactor Smart Today, Move Faster Tomorrow — Part 2: Plan Your Refactor Step by Step</title>
      <dc:creator>Agustín Rodríguez</dc:creator>
      <pubDate>Wed, 03 Sep 2025 18:31:07 +0000</pubDate>
      <link>https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-2-plan-your-refactor-step-by-step-1021</link>
      <guid>https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-2-plan-your-refactor-step-by-step-1021</guid>
      <description>&lt;p&gt;So, you've confirmed that your refactor is necessary.&lt;br&gt;
Now it's time to plan it right — because a poorly scoped or unstructured refactor is a trap that can drain weeks of work and leave everything worse than before.&lt;/p&gt;

&lt;p&gt;Let's break it down.&lt;/p&gt;




&lt;h3&gt;
  
  
  🎯 Choose the Right Strategy
&lt;/h3&gt;

&lt;p&gt;There's no single "best" approach to refactoring, but here are common strategies — and when to use them:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. &lt;strong&gt;Incremental Refactor (Recommended for Live Systems)&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Refactor bit by bit, keeping the system functional at all times.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ Pros: Safe, gradual, easier to test&lt;br&gt;
⚠️ Cons: Requires discipline and clear boundaries&lt;br&gt;
✅ Best for: Actively used systems, critical codebases, or anything in production&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  2. &lt;strong&gt;Branch-based Refactor (When Changes Are Too Invasive)&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Fork the code into a separate branch, refactor freely, and merge later.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ Pros: Total freedom to redesign&lt;br&gt;
⚠️ Cons: Merge hell, risk of long-living branches, hard to keep in sync&lt;br&gt;
✅ Best for: Isolated modules, internal tools, greenfield components&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  3. &lt;strong&gt;Strangler Fig Pattern (Great for Legacy Systems)&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Wrap and slowly replace legacy logic, one endpoint or feature at a time.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;✅ Pros: Legacy coexists with new code, safer evolution&lt;br&gt;
⚠️ Cons: Requires architectural support (e.g., routing layers, boundaries)&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  🗂️ Control the Scope or You'll Never Finish
&lt;/h3&gt;

&lt;p&gt;One of the biggest risks in a refactor is the &lt;strong&gt;infinite scope creep&lt;/strong&gt;.&lt;br&gt;
You touch one piece, which leads to another, and then another... and before you know it, it's a rewrite.&lt;/p&gt;

&lt;p&gt;Avoid this by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defining &lt;em&gt;clear boundaries&lt;/em&gt; — "Only refactor the email dispatch logic"&lt;/li&gt;
&lt;li&gt;Having &lt;em&gt;non-negotiable out-of-scope rules&lt;/em&gt; — "Don't rewrite the frontend now"&lt;/li&gt;
&lt;li&gt;Splitting the work into &lt;em&gt;atomic, testable steps&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 Tip: Track tasks in a checklist. Treat each step like a mini-feature.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧱 Pick an Architecture or Pattern (Don't Wing It)
&lt;/h3&gt;

&lt;p&gt;Before you start moving code around, ask yourself:&lt;br&gt;
&lt;strong&gt;What kind of structure are we aiming for?&lt;/strong&gt;&lt;br&gt;
Without a vision, you'll likely make it &lt;em&gt;different&lt;/em&gt;, not &lt;em&gt;better&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean or Hexagonal architecture&lt;/li&gt;
&lt;li&gt;Adapter pattern to swap external services&lt;/li&gt;
&lt;li&gt;Strategy pattern to simplify logic by behavior&lt;/li&gt;
&lt;li&gt;Service layer for reusable business logic&lt;/li&gt;
&lt;li&gt;Ports and adapters to isolate frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🧠 Refactor is not just renaming variables — it's about &lt;strong&gt;redesigning how things work&lt;/strong&gt; internally.&lt;/p&gt;




&lt;h3&gt;
  
  
  📦 Stabilize Interfaces (Create Contracts)
&lt;/h3&gt;

&lt;p&gt;Even during a refactor, some parts of your system &lt;strong&gt;can't change&lt;/strong&gt; — external APIs, third-party expectations, or other modules still depending on them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define &lt;strong&gt;stable interfaces&lt;/strong&gt; or DTOs (data transfer objects)&lt;/li&gt;
&lt;li&gt;Keep &lt;strong&gt;method signatures&lt;/strong&gt; consistent while you migrate under the hood&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;adapters&lt;/strong&gt; to convert legacy format to the new one temporarily&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes it easier to refactor one part without breaking everything else.&lt;/p&gt;




&lt;h3&gt;
  
  
  🚩 Use Feature Flags
&lt;/h3&gt;

&lt;p&gt;If your refactor affects a feature that's already live, &lt;strong&gt;wrap the new version in a flag&lt;/strong&gt; so you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test it in staging&lt;/li&gt;
&lt;li&gt;Gradually roll it out&lt;/li&gt;
&lt;li&gt;Roll back instantly if needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This adds safety — especially when combined with CI/CD pipelines.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧪 Define a Refactor Testing Strategy
&lt;/h3&gt;

&lt;p&gt;You need different levels of tests to support your refactor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unit tests for small modules&lt;/li&gt;
&lt;li&gt;Integration tests for connections between modules&lt;/li&gt;
&lt;li&gt;Regression tests to make sure nothing breaks&lt;/li&gt;
&lt;li&gt;(Optional) Snapshots or visual diffs for UIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔍 Also, use coverage tools to find &lt;strong&gt;untested danger zones&lt;/strong&gt; before you touch them.&lt;/p&gt;




&lt;h3&gt;
  
  
  🛠️ Checklist Before the First Commit
&lt;/h3&gt;

&lt;p&gt;Before writing any code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Refactor strategy selected (Incremental, Branch, Strangler)
&lt;/li&gt;
&lt;li&gt;[ ] Scope clearly defined and limited&lt;/li&gt;
&lt;li&gt;[ ] Architectural target or pattern chosen&lt;/li&gt;
&lt;li&gt;[ ] Interfaces/contracts stabilized&lt;/li&gt;
&lt;li&gt;[ ] Feature flags planned (if needed)&lt;/li&gt;
&lt;li&gt;[ ] Tests prepared or planned&lt;/li&gt;
&lt;li&gt;[ ] Metrics defined (to validate results later)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📚 Series Index — &lt;em&gt;Refactor Smart Today, Move Faster Tomorrow&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;A practical guide to refactoring without fear — from planning to validation.&lt;/p&gt;

&lt;p&gt;1️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-1-before-you-touch-a-line-of-code-3557"&gt;Before You Touch a Line of Code&lt;/a&gt;&lt;br&gt;&lt;br&gt;
2️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-2-plan-your-refactor-step-by-step-1021"&gt;Plan Your Refactor Step by Step&lt;/a&gt;&lt;br&gt;&lt;br&gt;
3️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-3-tools-that-save-you-from-yourself-mnj"&gt;Tools That Save You From Yourself&lt;/a&gt;&lt;br&gt;&lt;br&gt;
4️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-4-refactoring-without-regret-26bl"&gt;Refactoring Without Regret&lt;/a&gt;&lt;br&gt;&lt;br&gt;
5️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-5-after-the-refactor-how-to-know-it-worked-47km"&gt;After the Refactor: How to Know It Worked&lt;/a&gt;&lt;br&gt;&lt;br&gt;
✨ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-bonus-pack-4-lessons-to-refactor-smarter-2jpb"&gt;Bonus: 4 Lessons to Refactor Smarter (Not Harder)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cover image credit: &lt;a href="https://unsplash.com/photos/a-computer-screen-with-a-bunch-of-code-on-it-ieic5Tq8YMk" rel="noopener noreferrer"&gt;Chris Ried&lt;/a&gt;, via &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>softwaredevelopment</category>
      <category>development</category>
    </item>
    <item>
      <title>Refactor Smart Today, Move Faster Tomorrow - Part 1: Before You Touch a Line of Code</title>
      <dc:creator>Agustín Rodríguez</dc:creator>
      <pubDate>Wed, 27 Aug 2025 16:21:04 +0000</pubDate>
      <link>https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-1-before-you-touch-a-line-of-code-3557</link>
      <guid>https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-1-before-you-touch-a-line-of-code-3557</guid>
      <description>&lt;h3&gt;
  
  
  👀 Do You &lt;em&gt;Really&lt;/em&gt; Need a Refactor?
&lt;/h3&gt;

&lt;p&gt;Sometimes we're tempted to refactor just because the code "looks ugly", but that's not always a good enough reason.&lt;br&gt;
A solid refactor starts with a real, measurable need.&lt;/p&gt;

&lt;p&gt;Here are signs that a refactor is truly worth the effort:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;⚠️ &lt;strong&gt;One change breaks unrelated parts&lt;/strong&gt; — butterfly effect everywhere&lt;/li&gt;
&lt;li&gt;🔁 &lt;strong&gt;Duplicate logic&lt;/strong&gt; all over the place&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;Code is hard to understand&lt;/strong&gt;, even for the original author&lt;/li&gt;
&lt;li&gt;🐌 &lt;strong&gt;Poor performance&lt;/strong&gt; without obvious cause&lt;/li&gt;
&lt;li&gt;❌ &lt;strong&gt;Low or no test coverage&lt;/strong&gt;, making changes risky&lt;/li&gt;
&lt;li&gt;🧱 &lt;strong&gt;Tightly coupled modules&lt;/strong&gt; that prevent new features from being added&lt;/li&gt;
&lt;li&gt;🤯 &lt;strong&gt;Huge functions doing 10 things at once&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 When your codebase starts slowing you down, it's a clear sign that technical debt is taking its toll.&lt;/p&gt;




&lt;h3&gt;
  
  
  🎯 Define a Clear Goal
&lt;/h3&gt;

&lt;p&gt;Refactoring is not a goal in itself. Ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are we doing this to improve performance?&lt;/li&gt;
&lt;li&gt;Or to enable new features?&lt;/li&gt;
&lt;li&gt;Reduce bugs?&lt;/li&gt;
&lt;li&gt;Make code more testable?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔍 Pick one or two &lt;em&gt;primary objectives&lt;/em&gt;.&lt;br&gt;
A refactor without a clear goal is just &lt;strong&gt;impulsive rewriting&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  📊 Take a “Before” Snapshot
&lt;/h3&gt;

&lt;p&gt;Before touching anything, capture some baseline metrics. You'll need these to prove the refactor was actually worth it. Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execution time or load time&lt;/li&gt;
&lt;li&gt;Test coverage percentage&lt;/li&gt;
&lt;li&gt;Number of reported bugs&lt;/li&gt;
&lt;li&gt;Average dev time per feature&lt;/li&gt;
&lt;li&gt;Class/service coupling indicators&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;💡 Even a simple comparison table can be powerful to demonstrate improvement post-refactor.&lt;/p&gt;




&lt;h3&gt;
  
  
  🤝 Talk to the Business
&lt;/h3&gt;

&lt;p&gt;Technically, the code might scream "Refactor me!", but if business stakeholders don't see value, you'll face resistance or pressure to skip it.&lt;/p&gt;

&lt;p&gt;Tips for making the case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Translate it into risk: "this might fail in production if..."&lt;/li&gt;
&lt;li&gt;Show future impact: "every new feature here takes 30% longer"&lt;/li&gt;
&lt;li&gt;Sell it as an investment: "this will take 1 week and save 3 each month"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🚨 If you can't align with business goals, it might be better to postpone.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧨 Evaluate the Risks!!!
&lt;/h3&gt;

&lt;p&gt;Not all code is safe to touch. Some modules handle payments, email dispatch, automation, etc. Run a small internal risk audit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are there tests that cover this code?&lt;/li&gt;
&lt;li&gt;How often is it used?&lt;/li&gt;
&lt;li&gt;What happens if it fails?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✍️ Document the risks and decide if you need a &lt;strong&gt;rollback plan&lt;/strong&gt; (feature flags, toggles, manual fallback, etc.).&lt;/p&gt;




&lt;h3&gt;
  
  
  🔒 Not Everything Needs Refactoring
&lt;/h3&gt;

&lt;p&gt;Sometimes it's better to &lt;strong&gt;leave ugly but stable code alone&lt;/strong&gt; than to risk breaking something that works fine.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ TL;DR — Your Refactor Pre-Flight Checklist
&lt;/h3&gt;

&lt;p&gt;Before touching any code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Know &lt;strong&gt;why&lt;/strong&gt; you're refactoring&lt;/li&gt;
&lt;li&gt;[ ] Define &lt;strong&gt;clear, measurable goals&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Capture &lt;strong&gt;before-metrics&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Talk to stakeholders&lt;/li&gt;
&lt;li&gt;[ ] Understand the &lt;strong&gt;risks&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Be ready with a &lt;strong&gt;fallback plan&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  📚 Series Index — &lt;em&gt;Refactor Smart Today, Move Faster Tomorrow&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;A practical guide to refactoring without fear — from planning to validation.&lt;/p&gt;

&lt;p&gt;1️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-1-before-you-touch-a-line-of-code-3557"&gt;Before You Touch a Line of Code&lt;/a&gt;&lt;br&gt;&lt;br&gt;
2️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-2-plan-your-refactor-step-by-step-1021"&gt;Plan Your Refactor Step by Step&lt;/a&gt;&lt;br&gt;&lt;br&gt;
3️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-3-tools-that-save-you-from-yourself-mnj"&gt;Tools That Save You From Yourself&lt;/a&gt;&lt;br&gt;&lt;br&gt;
4️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-4-refactoring-without-regret-26bl"&gt;Refactoring Without Regret&lt;/a&gt;&lt;br&gt;&lt;br&gt;
5️⃣ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-part-5-after-the-refactor-how-to-know-it-worked-47km"&gt;After the Refactor: How to Know It Worked&lt;/a&gt;&lt;br&gt;&lt;br&gt;
✨ &lt;a href="https://dev.to/agusrdz/refactor-smart-today-move-faster-tomorrow-bonus-pack-4-lessons-to-refactor-smarter-2jpb"&gt;Bonus: 4 Lessons to Refactor Smarter (Not Harder)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cover image credit: &lt;a href="https://unsplash.com/photos/turned-on-monitor-displaying-programming-language-u2Ru4QBXA5Q" rel="noopener noreferrer"&gt;Mohammad Rahmani&lt;/a&gt;, via &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>cleancode</category>
      <category>development</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>🎨 Making Long Coding Sessions More Pleasant — The Story Behind Harmonia Theme</title>
      <dc:creator>Agustín Rodríguez</dc:creator>
      <pubDate>Fri, 15 Aug 2025 01:07:40 +0000</pubDate>
      <link>https://dev.to/agusrdz/making-long-coding-sessions-more-pleasant-the-story-behind-harmonia-theme-2390</link>
      <guid>https://dev.to/agusrdz/making-long-coding-sessions-more-pleasant-the-story-behind-harmonia-theme-2390</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A good theme isn’t just a color palette — it’s a tool to protect your focus, reduce fatigue, and make your editor feel like home.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  🧪 Why build a theme?
&lt;/h3&gt;

&lt;p&gt;I’ve always enjoyed fine-tuning my development environment — from terminal fonts to keyboard shortcuts. But I could never quite settle on a theme that felt truly coherent, balanced, and comfortable for long hours of work.&lt;/p&gt;

&lt;p&gt;So I decided to try something: build my own Visual Studio Code theme.&lt;/p&gt;

&lt;p&gt;Not as a designer, but as a developer — out of curiosity, to learn, and to see how much impact a well-crafted theme could really have.&lt;/p&gt;




&lt;h3&gt;
  
  
  🌙 Dark, soft, and focused — that’s Harmonia
&lt;/h3&gt;

&lt;p&gt;From the start, Harmonia had a clear goal: to be a dark, soft, visually consistent theme, especially tailored for web developers.&lt;/p&gt;

&lt;p&gt;I focused on the languages and file types I use the most: PHP, JavaScript (and friends like TypeScript and JSX), JSON, config files, Docker, Apache, Nginx, and log files.&lt;/p&gt;

&lt;p&gt;The idea was to highlight what matters without visual noise. A theme that feels calm and lets your code breathe.&lt;/p&gt;




&lt;h3&gt;
  
  
  🖌️ The color decisions
&lt;/h3&gt;

&lt;p&gt;Instead of choosing flashy or high-contrast colors, I took a more subtle approach:&lt;br&gt;
    • Soft yet deep background: dark enough to reduce eye strain, but not harsh black.&lt;br&gt;
    • Readable, rich foreground: avoiding pure white or washed-out grays.&lt;br&gt;
    • Syntax colors with character — not chaos: strong enough to be useful, but not overwhelming.&lt;/p&gt;

&lt;p&gt;Each color was tested and adjusted to feel consistent across different languages and syntaxes, without breaking the harmony of the overall palette.&lt;/p&gt;




&lt;h3&gt;
  
  
  👁️ Why colors matter
&lt;/h3&gt;

&lt;p&gt;We spend countless hours looking at our editors. A bad theme can be a constant source of visual fatigue, even if you don’t realize it.&lt;/p&gt;

&lt;p&gt;A well-balanced color scheme can help you:&lt;br&gt;
    • stay focused longer&lt;br&gt;
    • avoid headaches or eye strain&lt;br&gt;
    • actually enjoy the experience of coding a bit more&lt;/p&gt;

&lt;p&gt;In my opinion, a theme is part of developer ergonomics. Just like a good chair or a calibrated monitor. You don’t notice the value — until you use one that’s actually well made.&lt;/p&gt;




&lt;h3&gt;
  
  
  🧠 What I learned along the way
&lt;/h3&gt;

&lt;p&gt;Creating a theme is more technical than it might seem. I learned:&lt;br&gt;
    • how VS Code token scopes work&lt;br&gt;
    • how to group styles across languages and file types&lt;br&gt;
    • how to test palettes while keeping consistency&lt;br&gt;
    • how to package and publish to the VS Code Marketplace&lt;br&gt;
    • how to generate proper previews for other users to see what you see&lt;/p&gt;

&lt;p&gt;It wasn’t hard — but it was detail-heavy.&lt;/p&gt;

&lt;p&gt;And that made it fun.&lt;/p&gt;




&lt;h3&gt;
  
  
  ⚠️ About updates
&lt;/h3&gt;

&lt;p&gt;I work full-time, so updates may not come frequently — but I’ll continue improving Harmonia little by little, especially around the languages and tools I use most in web development.&lt;/p&gt;

&lt;p&gt;That includes PHP, JS/TS, JSON, configs, Dockerfiles, and log files.&lt;/p&gt;

&lt;p&gt;If time allows, I’d love to expand support for other languages and improve the theme’s scope coverage even more.&lt;/p&gt;




&lt;h3&gt;
  
  
  📦 Where to find it
&lt;/h3&gt;

&lt;p&gt;Harmonia Theme is available now on the Visual Studio Code Marketplace.&lt;/p&gt;

&lt;p&gt;🔗 &lt;a href="https://marketplace.visualstudio.com/items?itemName=AgusRdz.harmonia-theme" rel="noopener noreferrer"&gt;Direct link to the extension&lt;/a&gt;&lt;br&gt;
📸 &lt;a href="https://github.com/AgusRdz/harmonia-theme" rel="noopener noreferrer"&gt;Screenshots and changelog on GitHub&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🙌 Thanks for reading
&lt;/h3&gt;

&lt;p&gt;This was a small side project — but one that brought me a lot of satisfaction.&lt;/p&gt;

&lt;p&gt;If it helps even one more developer feel a bit more comfortable during a long coding session, it was totally worth it.&lt;/p&gt;

&lt;p&gt;And if you try it — I’d love to hear what you think.&lt;/p&gt;




&lt;p&gt;Cover image credit: &lt;a href="https://unsplash.com/photos/monitor-displaying-indexhtml-codes-_SgRNwAVNKw" rel="noopener noreferrer"&gt;Pankaj Patel&lt;/a&gt;, via &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>themes</category>
      <category>web</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>Blue-Green Deployment in a Local Environment with Docker</title>
      <dc:creator>Agustín Rodríguez</dc:creator>
      <pubDate>Tue, 28 Jan 2025 17:07:10 +0000</pubDate>
      <link>https://dev.to/agusrdz/blue-green-deployment-in-a-local-environment-with-docker-43j9</link>
      <guid>https://dev.to/agusrdz/blue-green-deployment-in-a-local-environment-with-docker-43j9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Blue-Green Deployment is a deployment strategy designed to minimize downtime and risks during application updates. This approach involves running two separate environments, Blue and Green, where one serves traffic (the active environment) while the other is idle or undergoing updates. Once the updates are validated in the idle environment, traffic is switched seamlessly, ensuring stability and minimizing disruptions.&lt;/p&gt;

&lt;p&gt;In this guide, we demonstrate how to implement Blue-Green Deployment using Docker in a local environment with Laravel as the example application. This approach is tailored for educational purposes, offering a hands-on way to grasp the fundamentals of Blue-Green Deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Docker for Blue-Green Deployment?
&lt;/h2&gt;

&lt;p&gt;Docker provides an efficient way to isolate and simulate environments for Blue-Green Deployment in a local setup. Using Docker containers, you can create independent "Blue" and "Green" environments, test changes safely, and switch traffic between them.&lt;/p&gt;

&lt;p&gt;This guide leverages Docker to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simulate real-world deployment behavior.&lt;/li&gt;
&lt;li&gt;Visualize the Blue-Green Deployment process in an accessible way.&lt;/li&gt;
&lt;li&gt;Replicate health checks and traffic routing, similar to setups on platforms like AWS ECS or Kubernetes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While there are other ways to test deployments locally, this method focuses on simplicity and clarity, allowing developers to understand the strategy without the complexity of managing cloud infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Test Locally?
&lt;/h2&gt;

&lt;p&gt;Testing Blue-Green Deployment locally provides several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Safe debugging: Identify issues in deployment scripts without impacting production.&lt;/li&gt;
&lt;li&gt;Replicating production workflows: Validate environment transitions, API integrations, and scheduled tasks.&lt;/li&gt;
&lt;li&gt;Downtime-free testing: Switch traffic seamlessly between containers, ensuring smooth user experiences.&lt;/li&gt;
&lt;li&gt;Hands-on learning: Gain a deep understanding of deployment strategies by observing their effects in real-time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This local setup enables you to confidently refine deployment strategies before scaling them to production environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demonstration Setup
&lt;/h2&gt;

&lt;p&gt;For this demonstration, the following components are used:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Nginx: Acts as the reverse proxy to route traffic to the active environment.&lt;/li&gt;
&lt;li&gt;Health checks: Monitor container readiness and decide when to switch traffic.&lt;/li&gt;
&lt;li&gt;Laravel: Example application to visualize environment transitions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Vital Role of Health Checks in Blue-Green Deployment
&lt;/h2&gt;

&lt;p&gt;One of the key components of this setup is the use of health checks. These checks continuously monitor the status of a container to determine if it is ready to handle traffic. Health checks are essential in Blue-Green Deployment, as they ensure stability and minimize risks during the transition between environments.&lt;/p&gt;

&lt;p&gt;In this local setup, health checks play the following roles:&lt;br&gt;
    1.  Simulating production behavior: Platforms like AWS ECS and Kubernetes rely heavily on health checks to determine if a service is operational. By defining health checks in our docker-compose.yml file, we replicate this behavior in a local environment, providing a close-to-real-world experience.&lt;br&gt;
    2.  Automating deployment decisions: The deployment script uses health checks to decide whether traffic can be routed to the new environment. If a container fails its health checks, the script avoids switching traffic and triggers a rollback to maintain application availability.&lt;br&gt;
    3.  Ensuring application readiness: Before switching traffic to a new environment, health checks validate that the new container is fully operational. This prevents downtime caused by incomplete deployments or application errors.&lt;/p&gt;
&lt;h2&gt;
  
  
  Health Check Configuration
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD-SHELL"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;curl&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-f&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;http://localhost&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;||&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;exit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;1"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;30s&lt;/span&gt;
  &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
  &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
  &lt;span class="na"&gt;start_period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;test: Runs a command to check if the container is responding. In this case, it sends an HTTP request to the application and expects a successful response.&lt;/li&gt;
&lt;li&gt;interval: Sets the frequency of health check execution.&lt;/li&gt;
&lt;li&gt;timeout: Defines how long the health check can take before it’s considered a failure.&lt;/li&gt;
&lt;li&gt;retries: Specifies the number of consecutive failures before the container is marked as unhealthy.&lt;/li&gt;
&lt;li&gt;start_period: Allows a grace period for the container to fully initialize before health checks start.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Visual Representation of Blue-Green Deployment
&lt;/h2&gt;

&lt;p&gt;Here’s a simplified diagram of the Blue-Green Deployment process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+-------------------+                   +--------------------+
|                   |                   |                    |
|   Active (Blue)   |  &amp;lt;--- Traffic ---&amp;gt;|    Idle (Green)    |
|                   |                   |                    |
+-------------------+                   +--------------------+
         ↑                                    ↑
         |                                    |
   Updates &amp;amp; Tests                     Updates &amp;amp; Tests
         |                                    |
         ↓                                    ↓
+-------------------+                   +--------------------+
|   New Green       |                   |   New Blue         |
|   Deployment      |                   |   Deployment       |
+-------------------+                   +--------------------+
         |                                    |
   Health Checks Passed              Health Checks Passed
         ↓                                    ↓
+-------------------+                   +--------------------+
|   Idle (Blue)     |   &amp;lt;--- Traffic ---|   Active (Green)   |
+-------------------+                   +--------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Health Checks Are Critical
&lt;/h2&gt;

&lt;p&gt;Health checks are the backbone of this Blue-Green Deployment strategy because they:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prevent downtime: Only containers that pass health checks receive traffic, ensuring users are always directed to a functional environment.&lt;/li&gt;
&lt;li&gt;Enable automated rollbacks: If a container fails its health checks, the script reverts to the previously active environment.&lt;/li&gt;
&lt;li&gt;Promote confidence: By validating the readiness of the new environment, health checks reduce the risk of deploying faulty updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Components and Files
&lt;/h2&gt;

&lt;p&gt;Here is an overview of the files used in this setup:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deployment Script: Automates the creation, switching, and rollback of Blue-Green environments.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;abin/install.sh&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;  &lt;span class="c"&gt;# Stop script execution on error&lt;/span&gt;

&lt;span class="nv"&gt;NGINX_CONF_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"./docker/nginx/active_backend.conf"&lt;/span&gt;
&lt;span class="nv"&gt;NGINX_CONTAINER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"app"&lt;/span&gt;
&lt;span class="nv"&gt;ENV_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;".env"&lt;/span&gt;

build_containers&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"📦 Building Docker containers..."&lt;/span&gt;
    docker compose build
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ Docker containers built successfully."&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

prepare_nginx_config&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"./docker/nginx"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"📂 Nginx directory not found. Creating it..."&lt;/span&gt;
        &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ./docker/nginx
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ Nginx directory created."&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

update_nginx_config&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;active_color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🔄 Updating Nginx configuration to route traffic to '&lt;/span&gt;&lt;span class="nv"&gt;$active_color&lt;/span&gt;&lt;span class="s2"&gt;' containers..."&lt;/span&gt;

    &lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NGINX_CONF_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOL&lt;/span&gt;&lt;span class="sh"&gt;
upstream app_backend {
    server &lt;/span&gt;&lt;span class="nv"&gt;$active_color&lt;/span&gt;&lt;span class="sh"&gt;:9000 max_fails=3 fail_timeout=30s;
}
&lt;/span&gt;&lt;span class="no"&gt;EOL

&lt;/span&gt;    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"📋 Copying Nginx configuration to the container..."&lt;/span&gt;
    docker &lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NGINX_CONF_PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NGINX_CONTAINER&lt;/span&gt;&lt;span class="s2"&gt;:/etc/nginx/conf.d/active_backend.conf"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🔁 Reloading Nginx to apply the new configuration..."&lt;/span&gt;
    docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NGINX_CONTAINER&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; nginx &lt;span class="nt"&gt;-s&lt;/span&gt; reload &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ Nginx configuration updated and reloaded successfully."&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

wait_for_health&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;container_prefix&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;retries&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5
    &lt;span class="nb"&gt;local &lt;/span&gt;unhealthy_found
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"⏳ Waiting for containers with prefix '&lt;/span&gt;&lt;span class="nv"&gt;$container_prefix&lt;/span&gt;&lt;span class="s2"&gt;' to become healthy..."&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt; retries &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 0 &lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
        &lt;/span&gt;&lt;span class="nv"&gt;unhealthy_found&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false

        &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;container_name &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;docker ps &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="s2"&gt;"name=&lt;/span&gt;&lt;span class="nv"&gt;$container_prefix&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; &lt;span class="s2"&gt;"{{.Names}}"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
            &lt;/span&gt;&lt;span class="nv"&gt;health_status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;docker inspect &lt;span class="nt"&gt;--format&lt;/span&gt; &lt;span class="s1"&gt;'{{if .State.Health}}{{.State.Health.Status}}{{else}}unknown{{end}}'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$container_name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"unknown"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$health_status&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"healthy"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
                &lt;/span&gt;&lt;span class="nv"&gt;unhealthy_found&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true
                echo&lt;/span&gt; &lt;span class="s2"&gt;"🚧 Container '&lt;/span&gt;&lt;span class="nv"&gt;$container_name&lt;/span&gt;&lt;span class="s2"&gt;' is not ready. Current status: &lt;/span&gt;&lt;span class="nv"&gt;$health_status&lt;/span&gt;&lt;span class="s2"&gt;."&lt;/span&gt;
            &lt;span class="k"&gt;fi
        done

        if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nv"&gt;$unhealthy_found&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
            &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ All containers with prefix '&lt;/span&gt;&lt;span class="nv"&gt;$container_prefix&lt;/span&gt;&lt;span class="s2"&gt;' are healthy."&lt;/span&gt;
            &lt;span class="k"&gt;return &lt;/span&gt;0
        &lt;span class="k"&gt;fi

        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"⏳ Retrying... (&lt;/span&gt;&lt;span class="nv"&gt;$retries&lt;/span&gt;&lt;span class="s2"&gt; retries left)"&lt;/span&gt;
        &lt;span class="o"&gt;((&lt;/span&gt;retries--&lt;span class="o"&gt;))&lt;/span&gt;
        &lt;span class="nb"&gt;sleep &lt;/span&gt;5
    &lt;span class="k"&gt;done

    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"❌ Error: Some containers with prefix '&lt;/span&gt;&lt;span class="nv"&gt;$container_prefix&lt;/span&gt;&lt;span class="s2"&gt;' are not healthy. Aborting deployment."&lt;/span&gt;
    rollback
    &lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="o"&gt;}&lt;/span&gt;

rollback&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🛑 Rolling back deployment. Ensuring the active environment remains intact."&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PREVIOUS_COLOR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🔄 Restoring CONTAINER_COLOR=&lt;/span&gt;&lt;span class="nv"&gt;$PREVIOUS_COLOR&lt;/span&gt;&lt;span class="s2"&gt; in .env."&lt;/span&gt;
        &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt;.bak &lt;span class="s2"&gt;"s/^CONTAINER_COLOR=.*/CONTAINER_COLOR=&lt;/span&gt;&lt;span class="nv"&gt;$PREVIOUS_COLOR&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;.bak"&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ Restored CONTAINER_COLOR=&lt;/span&gt;&lt;span class="nv"&gt;$PREVIOUS_COLOR&lt;/span&gt;&lt;span class="s2"&gt; in .env."&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🚧  No previous CONTAINER_COLOR found to restore."&lt;/span&gt;
    &lt;span class="k"&gt;fi

    if &lt;/span&gt;docker ps &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="s2"&gt;"name=green"&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; &lt;span class="s2"&gt;"{{.Names}}"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"green"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ Active environment 'green' remains intact."&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🛑 Stopping and removing 'blue' containers..."&lt;/span&gt;
        docker compose stop &lt;span class="s2"&gt;"blue"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1 &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true
        &lt;/span&gt;docker compose &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"blue"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1 &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true
    &lt;/span&gt;&lt;span class="k"&gt;elif &lt;/span&gt;docker ps &lt;span class="nt"&gt;--filter&lt;/span&gt; &lt;span class="s2"&gt;"name=blue"&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; &lt;span class="s2"&gt;"{{.Names}}"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"blue"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ Active environment 'blue' remains intact."&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🛑 Stopping and removing 'green' containers..."&lt;/span&gt;
        docker compose stop &lt;span class="s2"&gt;"green"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1 &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true
        &lt;/span&gt;docker compose &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"green"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1 &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true
    &lt;/span&gt;&lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"❌ No active environment detected after rollback. Manual intervention might be needed."&lt;/span&gt;
    &lt;span class="k"&gt;fi

    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🔄 Rollback completed."&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

update_env_file&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;active_color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;

    &lt;span class="c"&gt;# check if .env file exists&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"❌ .env file not found. Creating a new one..."&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"CONTAINER_COLOR=&lt;/span&gt;&lt;span class="nv"&gt;$active_color&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ Created .env file with CONTAINER_COLOR=&lt;/span&gt;&lt;span class="nv"&gt;$active_color&lt;/span&gt;&lt;span class="s2"&gt;."&lt;/span&gt;
        &lt;span class="k"&gt;return
    fi&lt;/span&gt;

    &lt;span class="c"&gt;# backup previous CONTAINER_COLOR value&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"^CONTAINER_COLOR="&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;PREVIOUS_COLOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"^CONTAINER_COLOR="&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'='&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 2&lt;span class="si"&gt;)&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"♻️  Backing up previous CONTAINER_COLOR=&lt;/span&gt;&lt;span class="nv"&gt;$PREVIOUS_COLOR&lt;/span&gt;&lt;span class="s2"&gt;."&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nv"&gt;PREVIOUS_COLOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;

    &lt;span class="c"&gt;# update CONTAINER_COLOR value in .env&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"^CONTAINER_COLOR="&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt;.bak &lt;span class="s2"&gt;"s/^CONTAINER_COLOR=.*/CONTAINER_COLOR=&lt;/span&gt;&lt;span class="nv"&gt;$active_color&lt;/span&gt;&lt;span class="s2"&gt;/"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🔄 Updated CONTAINER_COLOR=&lt;/span&gt;&lt;span class="nv"&gt;$active_color&lt;/span&gt;&lt;span class="s2"&gt; in .env"&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"CONTAINER_COLOR=&lt;/span&gt;&lt;span class="nv"&gt;$active_color&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
        &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🖋️ Added CONTAINER_COLOR=&lt;/span&gt;&lt;span class="nv"&gt;$active_color&lt;/span&gt;&lt;span class="s2"&gt; to .env"&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;

    &lt;span class="c"&gt;# remove backup file&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;.bak"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;.bak"&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

install_dependencies&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;container&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"📥 Installing dependencies in container '&lt;/span&gt;&lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="s2"&gt;'..."&lt;/span&gt;

    &lt;span class="c"&gt;# Install Laravel dependencies&lt;/span&gt;
    docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"composer install --no-dev --optimize-autoloader"&lt;/span&gt;
    docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"mkdir -p database &amp;amp;&amp;amp; touch database/database.sqlite"&lt;/span&gt;

    &lt;span class="c"&gt;# Permissions setup&lt;/span&gt;
    docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"chown www-data:www-data -R ./storage ./bootstrap ./database"&lt;/span&gt;
    docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"chmod -R 775 ./storage ./bootstrap/cache"&lt;/span&gt;

    &lt;span class="c"&gt;# Clear caches and run migrations&lt;/span&gt;
    docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"php artisan cache:clear"&lt;/span&gt;
    docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"php artisan config:clear"&lt;/span&gt;
    docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"php artisan route:clear"&lt;/span&gt;
    docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"php artisan view:clear"&lt;/span&gt;
    docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"php artisan migrate --force"&lt;/span&gt;

    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ Dependencies installed and database initialized successfully in container '&lt;/span&gt;&lt;span class="nv"&gt;$container&lt;/span&gt;&lt;span class="s2"&gt;'."&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

deploy&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;active&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
    &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;new&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;

    &lt;span class="c"&gt;# Update .env before deploying&lt;/span&gt;
    update_env_file &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🚀 Starting deployment. Current active environment: '&lt;/span&gt;&lt;span class="nv"&gt;$active&lt;/span&gt;&lt;span class="s2"&gt;'. Deploying to '&lt;/span&gt;&lt;span class="nv"&gt;$new&lt;/span&gt;&lt;span class="s2"&gt;'..."&lt;/span&gt;
    docker compose &lt;span class="nt"&gt;--profile&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; up &lt;span class="nt"&gt;-d&lt;/span&gt;
    wait_for_health &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    install_dependencies &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    update_nginx_config &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🗑️  Removing old environment: '&lt;/span&gt;&lt;span class="nv"&gt;$active&lt;/span&gt;&lt;span class="s2"&gt;'..."&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🛑 Stopping '&lt;/span&gt;&lt;span class="nv"&gt;$active&lt;/span&gt;&lt;span class="s2"&gt;' containers..."&lt;/span&gt;
    docker compose stop &lt;span class="nv"&gt;$active&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1 &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true
    echo&lt;/span&gt; &lt;span class="s2"&gt;"🗑️  Removing '&lt;/span&gt;&lt;span class="nv"&gt;$active&lt;/span&gt;&lt;span class="s2"&gt;' containers..."&lt;/span&gt;
    docker compose &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nv"&gt;$active&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1 &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true
    &lt;/span&gt;update_env_file &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$new&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ Deployment to '&lt;/span&gt;&lt;span class="nv"&gt;$new&lt;/span&gt;&lt;span class="s2"&gt;' completed successfully."&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

get_active_container&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"CONTAINER_COLOR"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"CONTAINER_COLOR"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ENV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'='&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; 2
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Main script logic&lt;/span&gt;
prepare_nginx_config
build_containers

&lt;span class="nv"&gt;ACTIVE_COLOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;get_active_container&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ACTIVE_COLOR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="c"&gt;# if no active container found, deploy 'blue'&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🟦 Initial setup. Bringing up 'blue' containers..."&lt;/span&gt;
    docker compose &lt;span class="nt"&gt;--profile&lt;/span&gt; blue up &lt;span class="nt"&gt;-d&lt;/span&gt;
    wait_for_health &lt;span class="s2"&gt;"blue"&lt;/span&gt;
    install_dependencies &lt;span class="s2"&gt;"blue"&lt;/span&gt;
    update_nginx_config &lt;span class="s2"&gt;"blue"&lt;/span&gt;
    update_env_file &lt;span class="s2"&gt;"blue"&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ACTIVE_COLOR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"green"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="c"&gt;# if the active is 'green', deploy 'blue'&lt;/span&gt;
    &lt;span class="nv"&gt;PREVIOUS_COLOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"green"&lt;/span&gt;
    deploy &lt;span class="s2"&gt;"green"&lt;/span&gt; &lt;span class="s2"&gt;"blue"&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ACTIVE_COLOR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"blue"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="c"&gt;# if the active is 'blue', deploy 'green'&lt;/span&gt;
    &lt;span class="nv"&gt;PREVIOUS_COLOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"blue"&lt;/span&gt;
    deploy &lt;span class="s2"&gt;"blue"&lt;/span&gt; &lt;span class="s2"&gt;"green"&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="c"&gt;# if the active is neither 'green' nor 'blue', reset to 'blue'&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🚧 Unexpected CONTAINER_COLOR value. Resetting to 'blue'..."&lt;/span&gt;
    &lt;span class="nv"&gt;PREVIOUS_COLOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;
    docker compose &lt;span class="nt"&gt;--profile&lt;/span&gt; blue up &lt;span class="nt"&gt;-d&lt;/span&gt;
    wait_for_health &lt;span class="s2"&gt;"blue"&lt;/span&gt;
    install_dependencies &lt;span class="s2"&gt;"blue"&lt;/span&gt;
    update_nginx_config &lt;span class="s2"&gt;"blue"&lt;/span&gt;
    update_env_file &lt;span class="s2"&gt;"blue"&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🎉 Deployment successful!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Nginx Configuration: Handles traffic routing to the active environment.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;nginx/default.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="err"&gt;server&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;listen&lt;/span&gt; &lt;span class="err"&gt;80&lt;/span&gt;&lt;span class="c"&gt;;
&lt;/span&gt;    &lt;span class="err"&gt;index&lt;/span&gt; &lt;span class="err"&gt;index.php&lt;/span&gt; &lt;span class="err"&gt;index.html&lt;/span&gt;&lt;span class="c"&gt;;
&lt;/span&gt;    &lt;span class="err"&gt;client_max_body_size&lt;/span&gt; &lt;span class="err"&gt;20M&lt;/span&gt;&lt;span class="c"&gt;;
&lt;/span&gt;    &lt;span class="err"&gt;root&lt;/span&gt; &lt;span class="err"&gt;/var/www/html/public&lt;/span&gt;&lt;span class="c"&gt;;
&lt;/span&gt;
    &lt;span class="err"&gt;location&lt;/span&gt; &lt;span class="err"&gt;/&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;try_files&lt;/span&gt; &lt;span class="err"&gt;$uri&lt;/span&gt; &lt;span class="err"&gt;$uri/&lt;/span&gt; &lt;span class="err"&gt;/index.php?$query_string&lt;/span&gt;&lt;span class="c"&gt;;
&lt;/span&gt;    &lt;span class="err"&gt;}&lt;/span&gt;

    &lt;span class="err"&gt;location&lt;/span&gt; &lt;span class="err"&gt;~&lt;/span&gt; &lt;span class="err"&gt;\.php$&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;fastcgi_pass&lt;/span&gt; &lt;span class="err"&gt;app_backend&lt;/span&gt;&lt;span class="c"&gt;;
&lt;/span&gt;        &lt;span class="err"&gt;fastcgi_param&lt;/span&gt; &lt;span class="err"&gt;SCRIPT_FILENAME&lt;/span&gt; &lt;span class="err"&gt;$document_root$fastcgi_script_name&lt;/span&gt;&lt;span class="c"&gt;;
&lt;/span&gt;        &lt;span class="err"&gt;include&lt;/span&gt; &lt;span class="err"&gt;fastcgi_params&lt;/span&gt;&lt;span class="c"&gt;;
&lt;/span&gt;    &lt;span class="err"&gt;}&lt;/span&gt;

    &lt;span class="err"&gt;location&lt;/span&gt; &lt;span class="err"&gt;~&lt;/span&gt; &lt;span class="err"&gt;/\.ht&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
        &lt;span class="err"&gt;deny&lt;/span&gt; &lt;span class="err"&gt;all&lt;/span&gt;&lt;span class="c"&gt;;
&lt;/span&gt;    &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;PHP-FPM Configuration: Manages PHP processes for Laravel.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;php/www.conf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;listen&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;9000&lt;/span&gt;
&lt;span class="py"&gt;user&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;www-data&lt;/span&gt;
&lt;span class="py"&gt;group&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;www-data&lt;/span&gt;

&lt;span class="nn"&gt;[www]&lt;/span&gt;
&lt;span class="py"&gt;pm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;dynamic&lt;/span&gt;
&lt;span class="py"&gt;pm.max_children&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;20&lt;/span&gt;
&lt;span class="py"&gt;pm.start_servers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;10&lt;/span&gt;
&lt;span class="py"&gt;pm.min_spare_servers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;5&lt;/span&gt;
&lt;span class="py"&gt;pm.max_spare_servers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Dockerfile: Sets up the Laravel environment with required dependencies.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;Dockerfile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; php:8.2.0-fpm&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /var/www/html&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    curl &lt;span class="se"&gt;\
&lt;/span&gt;    dos2unix &lt;span class="se"&gt;\
&lt;/span&gt;    git &lt;span class="se"&gt;\
&lt;/span&gt;    libonig-dev &lt;span class="se"&gt;\
&lt;/span&gt;    libpng-dev &lt;span class="se"&gt;\
&lt;/span&gt;    libxml2-dev &lt;span class="se"&gt;\
&lt;/span&gt;    libzip-dev &lt;span class="se"&gt;\
&lt;/span&gt;    unzip &lt;span class="se"&gt;\
&lt;/span&gt;    zip &lt;span class="se"&gt;\
&lt;/span&gt;    libfcgi0ldbl &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get clean &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; curl &lt;span class="nt"&gt;-sS&lt;/span&gt; https://getcomposer.org/installer | php &lt;span class="nt"&gt;--&lt;/span&gt; &lt;span class="nt"&gt;--install-dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/local/bin &lt;span class="nt"&gt;--filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;composer &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /var/www/html/storage /var/www/html/bootstrap/cache &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; :www-data ./bootstrap/cache &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; storage &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;cd &lt;/span&gt;storage/ &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; logs &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; framework/sessions &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; framework/views &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; framework/cache &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;chmod&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 775 framework logs app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; :www-data ./framework ./logs ./app &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    git config &lt;span class="nt"&gt;--global&lt;/span&gt; &lt;span class="nt"&gt;--add&lt;/span&gt; safe.directory &lt;span class="s1"&gt;'*'&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./scripts/start.sh /usr/local/bin/start.sh&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /usr/local/bin/start.sh
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["/usr/local/bin/start.sh"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Docker Compose: Defines the Blue-Green containers, Nginx, and health check configurations.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;blue&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blue&lt;/span&gt;
    &lt;span class="na"&gt;env_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.env&lt;/span&gt;
    &lt;span class="na"&gt;profiles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;blue&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./docker&lt;/span&gt;
      &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dockerfile&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./:/var/www/html&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./docker/supervisor/supervisord.conf:/etc/supervisor/supervisord.conf&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./docker/php/www.conf:/usr/local/etc/php-fpm.d/www.conf&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD-SHELL"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SCRIPT_FILENAME=/var/www/html/public/index.php&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;REQUEST_METHOD=GET&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;cgi-fcgi&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-bind&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-connect&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:9000&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;||&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;exit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;1"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;30s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
      &lt;span class="na"&gt;start_period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;

  &lt;span class="na"&gt;green&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;green&lt;/span&gt;
    &lt;span class="na"&gt;profiles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;green&lt;/span&gt;
    &lt;span class="na"&gt;env_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.env&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./docker&lt;/span&gt;
      &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dockerfile&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./:/var/www/html&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./docker/supervisor/supervisord.conf:/etc/supervisor/supervisord.conf&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./docker/php/www.conf:/usr/local/etc/php-fpm.d/www.conf&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD-SHELL"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SCRIPT_FILENAME=/var/www/html/public/index.php&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;REQUEST_METHOD=GET&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;cgi-fcgi&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-bind&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-connect&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:9000&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;||&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;exit&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;1"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;30s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
      &lt;span class="na"&gt;start_period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;

  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:alpine&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app&lt;/span&gt;
    &lt;span class="na"&gt;profiles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;blue&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;green&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${PORT-80}:80"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./:/var/www/html&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;curl"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-f"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;30s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
      &lt;span class="na"&gt;start_period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Health Checks in Action
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;When deploying updates:

&lt;ul&gt;
&lt;li&gt;A new environment (Blue or Green) is started.&lt;/li&gt;
&lt;li&gt;Health checks validate the container’s readiness.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If health checks pass:

&lt;ul&gt;
&lt;li&gt;Traffic is routed to the new environment.&lt;/li&gt;
&lt;li&gt;The old environment becomes idle, ready for future updates.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If health checks fail:

&lt;ul&gt;
&lt;li&gt;A rollback is triggered, and the active environment remains unchanged.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Automated Rollback Example
&lt;/h4&gt;

&lt;p&gt;The deployment script ensures a rollback occurs when health checks fail. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blue is active, and Green fails health checks.&lt;/li&gt;
&lt;li&gt;Traffic remains routed to Blue.&lt;/li&gt;
&lt;li&gt;The faulty Green container is removed, preserving application stability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Examples:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://youtu.be/SKwZpRnhCkY" rel="noopener noreferrer"&gt;🎥 Deployment demo&lt;/a&gt;: Visualizes the transition from Blue to Green.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://youtu.be/FZ9T3LmXBYs" rel="noopener noreferrer"&gt;🎥 Rollback demo&lt;/a&gt;: Demonstrates how rollbacks maintain stability when an update fails.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;This guide demonstrates how to simulate and understand Blue-Green Deployment using Docker in a local environment. By leveraging health checks, traffic switching, and automated rollbacks, you can minimize downtime and ensure stability during deployments. While this approach is simplified, the concepts can easily extend to production-grade systems.&lt;/p&gt;

&lt;p&gt;Use this setup to test and refine deployment strategies confidently before scaling to production.&lt;/p&gt;

&lt;p&gt;Full code in this &lt;a href="https://github.com/AgusRdz/blue-green-local" rel="noopener noreferrer"&gt;Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cover image credit: &lt;a href="https://unsplash.com/photos/turned-on-macbook-pro-wit-programming-codes-display-f77Bh3inUpE" rel="noopener noreferrer"&gt;Arnold Francisca&lt;/a&gt;, via Unsplash(&lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;https://unsplash.com/&lt;/a&gt;)&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>development</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Understanding Technical Debt: An Ally and a Challenge in Software Development</title>
      <dc:creator>Agustín Rodríguez</dc:creator>
      <pubDate>Sun, 10 Nov 2024 04:05:01 +0000</pubDate>
      <link>https://dev.to/agusrdz/understanding-technical-debt-an-ally-and-a-challenge-in-software-development-424i</link>
      <guid>https://dev.to/agusrdz/understanding-technical-debt-an-ally-and-a-challenge-in-software-development-424i</guid>
      <description>&lt;p&gt;Technical debt is a common term in the world of software development, but for many, it remains a vague and sometimes intimidating concept. Is it something bad? Does it mean the code is poorly written? The reality is more nuanced. Much like financial debt, technical debt isn’t something to be ashamed of. Instead, it’s a tool that can help us move forward faster in our projects—as long as we manage it wisely.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Technical Debt?
&lt;/h3&gt;

&lt;p&gt;Think of technical debt as those design and development shortcuts we sometimes take to deliver a product or feature faster. These decisions help us progress, but, just like financial debt, they come with “interest” that accumulates in the form of complexity, potential errors, and maintenance headaches down the road.&lt;/p&gt;

&lt;p&gt;For example, imagine your team is under pressure to launch a new app quickly. You might decide to skip some unit tests or use a simplified database structure just to get the product out the door. It works for now, but those shortcuts might create future problems, making the code harder to understand, modify, or debug. Sound familiar? Many of us have been there, and that’s okay—as long as we have a plan to clean things up later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Might It Be Necessary?
&lt;/h3&gt;

&lt;p&gt;Let’s say your team is building a minimum viable product (MVP) and you’re racing against the clock to beat your competition to market. In these high-stakes moments, time is everything. The business needs to see results fast, validate the idea, attract customers, and start generating revenue. Here’s where technical debt becomes a strategic choice: you build something that works now, even if it’s not perfect, to grab that opportunity.&lt;/p&gt;

&lt;p&gt;This isn’t just theory; it’s a reality for many startups and emerging companies. If you’re developing an e-commerce platform and you can roll out a basic payment feature in two days instead of spending two weeks on a perfect integration, you might choose speed. The key is knowing that you’ll need to revisit and improve that feature once you have the breathing room.&lt;/p&gt;

&lt;p&gt;These decisions aren’t inherently bad. In fact, they can be what drives a company’s initial success. But you need to understand the trade-offs and have a strategy for dealing with those compromises later.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Importance of “Paying” Technical Debt
&lt;/h3&gt;

&lt;p&gt;Just like financial debt, technical debt needs to be paid off, or at least managed. If you keep ignoring it, the “interest” can pile up, making your system harder to maintain and slowing down your team’s ability to innovate. Here’s what that can look like:&lt;/p&gt;

&lt;p&gt;Increased errors and failures: As your codebase grows, those quick-and-dirty solutions can start causing real problems. Bugs can spread more easily, and each change could have unexpected ripple effects.&lt;br&gt;
Costly maintenance: Fixing bugs and adding new features takes longer. Developers might spend hours just trying to understand convoluted code before they can even begin making changes, driving up costs and slowing progress.&lt;br&gt;
Talent loss: Working with messy, unmanageable code can be demotivating. Developers want to create, not constantly fight fires. If the frustration builds up, you might start losing valuable team members.&lt;br&gt;
Plus, technical debt can hurt your company’s reputation. If users start experiencing frequent bugs or performance issues, their trust in your product can erode—and that can be devastating.&lt;/p&gt;

&lt;h3&gt;
  
  
  Impact on Innovation
&lt;/h3&gt;

&lt;p&gt;Here’s a less obvious consequence: technical debt can stifle innovation. When your team is constantly patching up old problems or dealing with messy code, there’s less time and energy for brainstorming and developing new ideas. Companies that need to stay on the cutting edge can’t afford to have their innovation pipeline clogged by the past. Reducing technical debt frees up your team to focus on the future.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Lifecycle
&lt;/h3&gt;

&lt;p&gt;Managing technical debt is not a one-size-fits-all approach. In the early stages of a project—like when you’re developing an MVP—it might make sense to take on more debt to move quickly. But as your product matures and gains stability, the focus should shift to paying off that debt. Think of it as adjusting your strategy as the project evolves, making sure the debt doesn’t turn into a long-term burden.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prioritizing Technical Debt
&lt;/h3&gt;

&lt;p&gt;Not all technical debt is equal. Some areas of your code might be critical, while others are less impactful. If a part of your application affects user experience or security, it should be a top priority. Taking a business impact approach helps you make smarter decisions about where to focus your refactoring efforts. Using project management tools to visualize and prioritize technical debt can also be a game changer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tracking Tools
&lt;/h3&gt;

&lt;p&gt;Documenting and tracking technical debt is key to keeping it under control. Tools like Jira, Trello, or Notion let you log technical debt decisions, describe their impact, and set timelines for addressing them. This not only keeps the team on the same page but also shows stakeholders that you’re serious about maintaining code quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Investing in Quality Tools
&lt;/h3&gt;

&lt;p&gt;To manage and reduce technical debt, investing in quality tools is a must. These tools help catch issues early and can be integrated into your workflow to prevent new problems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For PHP: Tools like PHPStan, PHPMD, and PHP Metrics do a great job of analyzing code quality. PHPStan catches errors before they’re even run, PHPMD flags bad practices, and PHP Metrics provides complexity analysis.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For JavaScript and TypeScript:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ESLint: This is a must-have for any JavaScript project. It can be configured to work seamlessly with TypeScript, catching more complex issues and ensuring clean code.&lt;/li&gt;
&lt;li&gt;Prettier: It’s just a code formatter, but having uniform code styling across your team can make a world of difference.&lt;/li&gt;
&lt;li&gt;JSHint: It’s not as popular in modern projects, but it’s still handy for older codebases or simpler setups.&lt;/li&gt;
&lt;li&gt;TypeScript: This is more than a tool—it’s a game changer. TypeScript’s static typing can catch errors before they become bugs, making your codebase safer and clearer. While many projects still use plain JavaScript, adopting TypeScript can be a smart move to reduce long-term debt.
SonarQube: This tool works across multiple languages, including JavaScript, TypeScript, PHP, and more. It scans for security vulnerabilities, bugs, and other issues, giving you a clear view of your code quality.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Balancing with Team Productivity
&lt;/h3&gt;

&lt;p&gt;Balancing technical debt reduction with productivity is tricky. Spending too much time on refactoring can slow down business goals, but ignoring it can create bigger problems later. One approach is to regularly schedule time for debt reduction without compromising key deliverables. It’s all about finding that sweet spot where you can address debt while still pushing forward.&lt;/p&gt;

&lt;h3&gt;
  
  
  Human and Motivational Aspects
&lt;/h3&gt;

&lt;p&gt;Finally, let’s talk about the human side. Working with clean, maintainable code isn’t just about efficiency—it’s about team morale. Developers want to build and create, not feel bogged down by messy code. Addressing technical debt can boost motivation and make your team happier. A positive environment means better retention and a more energized team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In the end, technical debt is a double-edged sword. It can accelerate progress when used wisely but become a serious liability if left unmanaged. The key is understanding that technical debt is part of the journey, not a failure. By making strategic decisions, investing in quality tools, and fostering a team culture that values maintainable code, you can leverage technical debt to your advantage while ensuring your projects remain sustainable and scalable in the long run.&lt;/p&gt;

&lt;p&gt;So, don’t fear technical debt—manage it, plan for it, and use it as a tool to keep your projects moving forward. After all, the best codebase is one that balances short-term wins with long-term stability.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover image credit: &lt;a href="https://www.pexels.com/photo/creative-internet-typing-abstract-6212801/" rel="noopener noreferrer"&gt;Markus Spiske&lt;/a&gt;, via &lt;a href="https://www.pexels.com" rel="noopener noreferrer"&gt;Pexels&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>technicaldebt</category>
      <category>programming</category>
      <category>development</category>
    </item>
  </channel>
</rss>
