<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[CodeSmash]]></title><description><![CDATA[CodeSmash]]></description><link>https://codesmash.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1698098024773/OvXFV41en.png</url><title>CodeSmash</title><link>https://codesmash.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 17 Apr 2026 13:23:05 GMT</lastBuildDate><atom:link href="https://codesmash.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Vibe Is Free. Cleanup Won’t Be.]]></title><description><![CDATA[I’ve been in this game long enough to remember when Delphi came with a promise to embrace everyone to write their own programs. I recall when all visual “website builders” would kill web development. I’ve heard the same pitch when no-code/low-code to...]]></description><link>https://codesmash.dev/vibe-is-free-cleanup-wont-be</link><guid isPermaLink="true">https://codesmash.dev/vibe-is-free-cleanup-wont-be</guid><category><![CDATA[vibe coding]]></category><category><![CDATA[AI]]></category><category><![CDATA[#ai-tools]]></category><category><![CDATA[engineering]]></category><category><![CDATA[coding]]></category><category><![CDATA[management]]></category><category><![CDATA[review]]></category><category><![CDATA[Pull Requests]]></category><dc:creator><![CDATA[Dominik Szymański]]></dc:creator><pubDate>Tue, 27 Jan 2026 13:36:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1769517915520/6bc36975-3c63-44cb-9ae3-896bdeb67e99.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I’ve been in this game long enough to remember when Delphi came with a promise to embrace everyone to write their own programs. I recall when all visual “website builders” would kill web development. I’ve heard the same pitch when no-code/low-code tools were gaining momentum. Now, standing here in 2025, I’m watching the latest "miracle": <strong>Vibe Coding.</strong> The pitch is intoxicating. You sit in front of a sleek IDE (or console if you want to feel fancier), you describe a feature in plain English (or other language), and you watch the code miraculously appearing in 100’s of lines per minute. You aren't writing code anymore, nor doing any "engineering" in the traditional sense - you’re steering a vibe. And for a moment, it feels like magic. The velocity is vertical. You’re shipping features before the new JS framework has been announced.  </p>
<p>But as a seasoned engineer who has spent countless hours cleaning up "miracles," I have a clear warning: the bill will come <strong>due.</strong> We are currently living through the "free" phase of AI-generated code, but technical debt has never been free, and it never will be. The current debt is more like a short-term, high-interest loan, and most teams aren't ready—or willing—to repay it after racing ahead at breakneck speed.</p>
<h2 id="heading-speed-vs-skill">Speed vs. Skill</h2>
<p>The industry suddenly has a 700-horsepower Italian supercar for $20 a month. In the hands of a professional, it's a marvel—a driver quickly learns its limits and pushes it with skill, mastering physics with precision rather than relying on "vibe."</p>
<p>Now picture a golf cart driver in the same supercar. On a straight, they floor it and feel invincible, trusting the smart safety features. But at the first real corner, the illusion ends—inevitably, the car crashes.</p>
<p>My warning is this: AI coding tools are that supercar. If you’re a seasoned engineer who understands the underlying memory management, database locking strategies, and the nuances of distributed systems, these tools are incredible. But if you’re "vibe coding" without fundamentals, you aren’t in control—you are heading straight for a crash. This risk multiplies if your work affects production systems or customers, not just your own sandbox.</p>
<h3 id="heading-comprehension-debt">Comprehension Debt</h3>
<p>I recall a day when I had to convince C-suite executives that, during a high-growth phase, we had accumulated technical debt and that, even if we doubled the team's size, we would not be able to double output. That was the old days, when technical debt was “human-made”. We took shortcuts, and we knew where the bodies were buried - because we buried them.</p>
<p>Now the AI-induced debt is different. It’s what I call <strong>Comprehension Debt.</strong> When an LLM generates 500 lines of code for a complex feature request, and you "accept" it because it passes the happy-path test (or vibe test), you have just introduced a block of logic into your system that no human fully understands (aka AI slop). When I’m meeting with my tech fellow, I hear that while development speed has increased by 30-40% across many teams, <strong>maintenance costs have spiked.</strong></p>
<p>Why? Because when that code breaks at 3:00 AM on a Sunday, the following happens:</p>
<ol>
<li><p><strong>Zero Intentionality:</strong> The AI lacked a rationale; it had only a probability distribution. It didn't "decide" to use a specific pattern because it anticipated future scaling; it used it because it was common in its training data.</p>
</li>
<li><p><strong>Context Fragmentation:</strong> The AI sees a window of code - a "context window." It doesn't know your database has a specific quirk with concurrent writes to handle Black Friday traffic, nor does it know that your storage bucket has a specific lifecycle policy that will delete the files it’s trying to reference.</p>
</li>
<li><p><strong>The Hallucination of Robustness:</strong> AI code often looks nice. Perfect naming conventions, includes comments, and sometimes uses a “smart” approach to solve a problem. Your vibes are lured into a false sense of security as code appears to be the work of a senior developer. The tool that you hold in your hand is not a Cyberpunk surgical robot; it’s a big hammer that looks like a surgical tool.</p>
</li>
</ol>
<h3 id="heading-big-hammer-and-the-broken-fingers">Big Hammer and the Broken Fingers</h3>
<p>Vibe coding is a massive hammer. In skilled hands, it’s the most efficient tool ever created (”It takes a hammer to get the job done”). Do you know how to use a hammer? At the end of the day, you are holding a nail with one hand and a hammer in the other. Are you skilled enough not to break all your fingers?</p>
<p>I’ve never seen in my career a software engineer whose only purpose was to spit out lines of code as fast as possible to solve a problem with the highest probability of success. It was always a mix of responsibilities, starting with clarifying specifications and moving into system engineering, everything bounded by context - usually undocumented. Writing code has always been the easiest part of the process. Fundamentals had not changed; they are the only thing standing between a functioning product and a catastrophic failure. I’m talking about:</p>
<ol>
<li><p><strong>Corner Cases:</strong> Be warned - AI is good at the average case, but often fails at unique edge cases, such as race conditions, network timeouts, or full disk scenarios. Overlooking these can cause critical failures. You delivered your personal CRM in a week of vibe coding, and it’s perfectly suited to your needs. Hey, maybe your use cases are not so unique after all. But you saved $12 a month on your “old” CRM subscription.</p>
</li>
<li><p><strong>System Boundaries &amp; Execution Environments</strong><br /> An LLM can write a perfect Python script, but it doesn't know it's running in a memory-constrained Lambda function. It doesn't know that the "vibe" it just generated will trigger an O(n2) complexity spike that times out the gateway.<br /> For example, consider a simple data transformation. The AI might suggest:<br /> T(n)=O(n2)<br /> Because it looks "clean" in the code editor. A seasoned engineer sees the number growing to 1,000,000 in production and knows that the "vibe" is actually a ticking time bomb.</p>
</li>
<li><p><strong>Context Management:</strong> An AI sees a window of code (sometimes it’s even just one file). An engineer sees a living ecosystem. The AI doesn't know your cloud bill is about to quadruple, even though it suggested a recursive Lambda call.  </p>
</li>
</ol>
<h2 id="heading-the-2027-wake-up-call">The 2027 Wake-Up Call</h2>
<p>I predict that over the next two years, any company that ignores tech debt will face a major “Great Refactoring” crisis - though they likely won’t admit it. Teams that replaced senior oversight with "vibe-heavy" approaches will become trapped by fragile, unmanageable codebases. The risk is real: these systems could become too complex and costly to repair or change.</p>
<p>We are already seeing the signs. Pull request review times have tripled in some organizations because reviewers now have to sift through mountains of "plausible-looking" but subtly broken AI code. Open source projects are blocking PR requests (after decades of asking for contributions). This shift is meaningful. Open source (and communities around it) is the heart of the IT ecosystem, and it’s the key (underpaid) driver of IT growth in the last 30 years. We are one of the most open industries, where not only knowledge is shared for free but also the results of the work (Python, Ruby, Linux, Git, etc.). Yet we are closing the gates to AI, not curated, slop being poured into the fundamentals of the industry.</p>
<h3 id="heading-craftsmanship-in-the-age-of-ai">Craftsmanship in the Age of AI</h3>
<p>Am I anti-AI? Not at all. I use a wide set of these tools every day. But I use them with the healthy skepticism of a man who has seen too many "magic" solutions turn into technical nightmares.</p>
<p>True craftsmanship in 2026 isn't about how fast you can type or how well you can prompt (even though every AI company will tell you a different story). It’s about:</p>
<ul>
<li><p><strong>The Rigorous Review:</strong> Treating AI code with <em>more</em> suspicion than human code. It’s your phone number that will ring at 3 AM if your app goes down.</p>
</li>
<li><p><strong>Defensive Architecture:</strong> Building systems that are modular enough that when an AI-generated component fails, it doesn't take down the whole ship. Where the context is small enough for an LLM to handle.</p>
</li>
<li><p><strong>Fundamental Literacy:</strong> Knowing enough about the "boring" stuff - protocols, data structures, and memory - to spot the lie in the AI’s beautiful output.</p>
</li>
</ul>
<p>The era of "free" tech debt is coming to an end. My final warning: the reality of production is returning. Don't discard your engineering books - you'll need them to repair what "vibe coding" leaves behind. Don’’t replace your engineering team with agents (workflows).</p>
<h2 id="heading-look-right-audit">“Look Right” Audit</h2>
<p>As a seasoned engineer, I’ve realized that the most dangerous part of "vibe coding" isn't the AI - it's the reviewer's competency. When code is generated in seconds, our brains naturally want to review it in the same amount of time. We "skim the vibe" instead of "auditing the logic". We are not spitting out 500 LOC per 10 minutes to spend 3 hours to understand - don’t we? How do you justify to your manager that you have your feature done, it looks alright, but you would like to understand the code you will push to production soon? No, you are becoming a bottleneck, that’s perceived by the manager with a whip.</p>
<p>To survive the next two years of high-interest tech debt, we have to treat AI-generated code with <strong>higher</strong> suspicion than a junior dev’s PR. Here is my personal "AI checklist":</p>
<h3 id="heading-context-amp-intent">Context &amp; Intent</h3>
<ul>
<li><p><strong>Why Alignment:</strong> Does this PR actually solve the business requirement, or did the AI solve a <em>similar</em> problem it found in its training data?</p>
</li>
<li><p><strong>Scope Creep (”While I'm At It" Trap):</strong> Did the AI refactor or change logic in files unrelated to the ticket? LLMs love to "clean up" things they don't understand, often breaking hidden invariants.</p>
</li>
<li><p><strong>Domain Accuracy:</strong> Does the code use our specific domain terminology (e.g., SaaS_Subscription) or generic AI terms (e.g., User_Level)?</p>
</li>
</ul>
<h3 id="heading-system-logic">System Logic</h3>
<ul>
<li><p><strong>"N+1" and Complexity Check:</strong> Did the AI suggest a clean-looking loop that secretly makes 100 database calls or has an O(n2) complexity on a high-volume path? Is there a long if/else statement?</p>
</li>
<li><p><strong>State &amp; Race Conditions:</strong> If this code runs in a distributed environment, are there locks? Is the state handled safely? (AI is notoriously "single-threaded" in its reasoning).</p>
</li>
<li><p><strong>"Empty Room" Test:</strong> What happens if the input is null, an empty string, or an array of 1,000,000 items? AI often ignores the 1% edge cases, and it will happen on Friday evening.</p>
</li>
<li><p><strong>Dependency Hallucination:</strong> Are all imports real, internal libraries? Or did the AI "invent" a utility function that looks like it <em>should</em> exist? Unused imports removed? What about variables or assumed configuration values? Are you reusing internal dependencies, or does every PR create a new one that does the same thing?</p>
</li>
<li><p><strong>Config Check: The local</strong> environment (where development happens) often differs from the production environment. Can code generated from a local config be used in production?</p>
</li>
</ul>
<h3 id="heading-the-infrastructure-amp-security-audit">The Infrastructure &amp; Security Audit</h3>
<ul>
<li><p><strong>Resource Cleanup:</strong> Are database connections, file handles, or memory buffers explicitly closed?</p>
</li>
<li><p><strong>The Secret Leak:</strong> Did the AI suggest hardcoding a "placeholder" API key or an insecure http:// endpoint? Is it using the same security patterns as you have in other parts of the application?</p>
</li>
<li><p><strong>Input Sanitization:</strong> Is there a raw SQL string or an unvalidated user input being passed to an OS command? AI prioritizes "working code" over "secure code" by default.</p>
</li>
</ul>
<h2 id="heading-conclusion-craftsmanship-is-the-new-premium">Conclusion: Craftsmanship is the New Premium.</h2>
<p>Am I anti-AI? Absolutely not. I am enthusiastic about the fact that I can now prototype an idea in an afternoon. These tools are the most significant leap in productivity since the invention of the high-level language.</p>
<p>But we must stop pretending that the tool replaces the craftsman.</p>
<p>True craftsmanship in 2026 isn't about how fast you can type or how well you can prompt. It’s about judgment. It’s about knowing when to say "No" to the AI’s suggestion. It’s about understanding the database structure, the execution environment, and the corner cases so well that you can spot the one line of "vibe" that will take down the entire system.</p>
<p>The era of "free" tech debt is ending. The "vibes" are fading, and the harsh light of production reality is turning back on. If you want to keep your fingers intact, stop blindly swinging the big hammer. Put on your seatbelt, learn the physics of the car, and remember:</p>
<p><strong>Code is easy, engineering is hard.</strong></p>
]]></content:encoded></item><item><title><![CDATA[Why I Ditched Docker for Podman (And You Should Too)]]></title><description><![CDATA[Beginnings
I'm old enough to remember when Vagrant looked like a promised land where every development environment would look the same. Differences between language versions, as well as some unusual OS version differences, resulted in a few days of u...]]></description><link>https://codesmash.dev/why-i-ditched-docker-for-podman-and-you-should-too</link><guid isPermaLink="true">https://codesmash.dev/why-i-ditched-docker-for-podman-and-you-should-too</guid><category><![CDATA[podman]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Kubernetes]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Dominik Szymański]]></dc:creator><pubDate>Thu, 04 Sep 2025 07:36:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/qMVR2YhOVQI/upload/ff5f28b79266f1737ba9b66092c75cde.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-beginnings">Beginnings</h2>
<p>I'm old enough to remember when Vagrant looked like a promised land where every development environment would look the same. Differences between language versions, as well as some unusual OS version differences, resulted in a few days of unproductive debugging of your development environment. I've had similar excitement when I started my first Docker Swarm (who uses that these days?!) - it felt revolutionary. Docker wasn't just a tool - it fundamentally changed how we thought about application development and deployment. Having a repeatable, separated environment from your local system was refreshing and looked like a superpower. It has become a must-have tool for every engineer. "<em>Just Dockerize it</em>" became my go-to solution for pretty much everything. Sure, architecture or defining a new Docker image could be a bit finicky at times, but hey, that's just how things worked. Is the persistent dockerd daemon eating upresources in the background with root privileges, just the price of doing business? I thought so.</p>
<p>If you are in this industry long enough, there is one pattern that emerges every day. Everybody begins questioning the "that's just how it's done" mentality. Along the way, the quiet Docker daemon running in the background felt less like a comfortable constant and more like a ticking bomb. More and more ways to explore this vulnerability emerged:</p>
<p><strong>2019-02-11 - CVE-2019-5736 (runC container escape):</strong> lets a process in a container overwrite the host’s runc binary → full host compromise if exploited.</p>
<p><strong>2022-03-07 - CVE-2022-0847 “Dirty Pipe” (Linux kernel):</strong> read-only file overwrite in kernel; practical container-to-host abuse scenarios documented by Docker/Sysdig. </p>
<p><strong>2022-03-07 - CVE-2022-0492 (cgroups v1 release_agent):</strong> privilege escalation / container escape via cgroups v1; mitigations via seccomp/AppArmor/SELinux. </p>
<p><strong>2024-01-31 - CVE-2024-21626 (runC “Leaky Vessels”):</strong> fd leak + process.cwd issues enabling host FS access and potential escape; fixed in runC <strong>1.1.12</strong> (Docker Engine ≥ <strong>25.0.2</strong>). </p>
<p><strong>2024-02-01 - CVE-2024-23651/23652/23653 (BuildKit, “Leaky Vessels”):</strong> build-time issues that can affect host files; fixed in BuildKit <strong>0.12.5</strong>. </p>
<p><strong>2024-09-23 - In-the-wild cryptojacking campaign:</strong> attackers targeted exposed Docker APIs and microservices. </p>
<p><strong>2024-10-01 - Docker API swarm botnet campaign:</strong> cryptojacking via exposed Docker Engine API (<a target="_blank" href="https://securitylabs.datadoghq.com/articles/threat-actors-leveraging-docker-swarm-kubernetes-mine-cryptocurrency/">details</a>).</p>
<p>I had been seeking an alternative (I assumed that someone had already questioned the status quo), and that's how I stumbled into Podman territory. It began as casual curiosity - "<em>Hey, let me check out this thing</em>" - turned into a complete overhaul of my container workflows and pulled me into using Fedora in my home lab. And honestly? I wish I'd made the switch sooner.</p>
<h2 id="heading-daemonless">Daemonless</h2>
<p>Here's the fundamental issue that kept me awake: Docker's entire architecture is built around a persistent background service - the dockerd daemon. Whenever you run a docker command, you're actually talking to this daemon, which then does the heavy lifting. Sounds about right?</p>
<p>Yes?!</p>
<p>Or rather NO, because this daemon runs with root privileges. Always. And if something goes south with a daemon - innocent bug, a crash, or worst case scenario, a security exploit - your entire container ecosystem is potentially compromised. Not just the containers, daemon, or resource that you assigned to it, but the whole host system. It was a huge relief that Podman threw this model out the window. No daemon, no processes running in the background. When you run <code>podman run my-app</code>, the container becomes a direct child of your command. And it is running under your user privileges. Simple architecture change with huge implications:</p>
<h3 id="heading-security-that-actually-makes-sense">Security that actually makes sense:</h3>
<p>Remember those late-night security advisories about Docker daemon vulnerabilities (ex., when dockerd was misconfigured to listen on TCP:2375 without TLS, attackers could spin up privileged containers remotely)? With Podman, even if someone somehow escalates privileges inside a container to root level, they're still just an unprivileged user on the actual host. It significantly reduces the surface of an attack.</p>
<h3 id="heading-no-more-single-points-of-failure">No more single points of failure:</h3>
<p>Usually Docker daemon runs just fine. But when hiccups kick in - oh boy, hold your hats, as it will take down multiple containers at once. With Podman when one container crashed, the other kept running like nothing happened. It makes so much sense, and it's built in the spirit of hermetization.</p>
<h3 id="heading-lighter-resource-footprint">Lighter resource footprint:</h3>
<p>I had been surprised when my MacBook M2 Pro started to get warmer when left unattended. After a brief investigation (with Activity Monitor), it was obvious - Docker never knows when to stop. No constantly running daemon means less memory usage. Unfortunately, running a container using Podman can be a different story (ekhm: https://blog.podman.io/2025/06/podman-and-apple-rosetta/) - yet the thing is getting better: https://blog.podman.io/2025/08/podman-5-6-released-rosetta-status-update/.</p>
<h2 id="heading-where-podman-really-shines">Where Podman Really Shines</h2>
<p>Beyond the obvious daemon advantages, Podman brings some genuinely clever features that make day-to-day container work more pleasant:</p>
<p><strong>Systemd integration that doesn't suck:</strong> This one's huge if you're working on Linux servers (most of us are). Podman justgenerates proper systemd unit files. Boom, your container is a first-class citizen in the Linux service ecosystem. Boot dependencies, automatic restarts, resource limits - it all just works. I can run <code>podman generate systemd --name my-app</code> and get a clean service file. Afterwards, I can enable, start, stop, and monitor with standard systemctl commands. Say bye-bye to third-party process managers.</p>
<p><strong>Kubernetes alignment that's not just marketing:</strong> Since Red Hat (the folks behind Podman) is also a major Kubernetes contributor, the tool feels like it was designed with K8s in mind from day one. The native pod support isn't just a bolt-on feature - it's central to how Podman works. I do not need to run k3s or any local substitute for Kubernetes. Now, I can prototype multi-container applications as Podman pods locally. Then I just generate Kubernetes YAML directly from those pods with podman generate kube. My local development environment actually looks like what I'm going to deploy. This was revolutionary when I had to take over the responsibility of managing and developing a quite complex cluster.</p>
<p><strong>The Unix philosophy done right:</strong> Instead of trying to be everything to everyone, Podman focuses on running containers well and delegates specialized tasks to purpose - built tools. Need to build images with fine - grained control? That's Buildah. Want to inspect or copy images between registries? Skopeo's your friend. I can use the best tool for each job. I'm no longer stuck with whatever image-building quirks Docker decides to implement.</p>
<h2 id="heading-the-migration-that-wasnt-really-a-migration">The Migration That Wasn't Really a Migration</h2>
<p>Here's the part that surprised me most: switching from Docker to Podman was almost seamless. The Podman folks clearly understood that creating the next standard would not let them win the market, and they just adhered to the known CLI tool. I literally just aliased <code>docker=podman</code> in my shell and carried on with life. <code>podman run, podman build, podman ps</code> - they all behave exactly like their Docker counterparts. My existing Dockerfiles worked without modification. My muscle memory didn't need retraining.</p>
<p>Though there were a few places where I did hit differences that were actually improvements in disguise:</p>
<ul>
<li><p>Privileged ports in rootless mode not working? Good! That's security working as intended. A reverse proxy setup is a better architecture anyway.</p>
</li>
<li><p>Some volume permission quirks? Yes - but it's a small price, and again - if you do it right, you are limiting the scope of possible attack.</p>
</li>
<li><p>A few legacy tools that expected the Docker socket? If there is no support by now, just remember that Podman can expose a Docker-compatible API if needed.</p>
</li>
<li><p>If your Docker Compose workflow is overly complex, just convert it to Kubernetes YAML. We all use Kubernetes these days, so why even bother about this? Having the same layout for development and production is a huge bonus of doing so.</p>
</li>
</ul>
<h2 id="heading-the-real-world-difference">The Real-World Difference</h2>
<p>After six months of running Podman in production, here's what I've noticed:</p>
<p>I'm sleeping much better. Because I'm personally responsible for security, I do not have to check if every container is running in rootless mode. Something that I did not think I would benefit from is that my monitoring dashboards show cleaner resource usage patterns. Don't get me wrong - Docker isn't going anywhere. It has massive momentum, a mature ecosystem, and plenty of organizational inertia keeping it in place. But for new projects, or if you are able to make technical decisions based on merit rather than legacy, Podman represents a clear evolution in container technology. More secure by design, more aligned with Linux system management practices, and more thoughtfully architected for the way we actually deploy containers in 2025. The best way forward is to question the assumptions you didn't even realize you were making.</p>
<h2 id="heading-fastapi-migration-guide-from-docker-to-podman">FastAPI Migration Guide: From Docker to Podman</h2>
<p>Just to prove how easy transition can be, here's a practical walkthrough of migrating a FastAPI application from Docker to Podman.  </p>
<h3 id="heading-what-youll-need">What You'll Need</h3>
<p>Your existing FastAPI project with its Dockerfile and requirements.txt</p>
<p>Podman is installed on your system:</p>
<ul>
<li><p>Ubuntu/Debian: sudo apt update &amp;&amp; sudo apt install podman</p>
</li>
<li><p>Fedora/RHEL: sudo dnf install podman</p>
</li>
<li><p>macOS: Grab Podman Desktop for a GUI experience</p>
</li>
<li><p>Windows: If you are not a C# developer - stop doing this to yourself and just use Linux: https://www.youtube.com/watch?v=S_RqZG6YR5M</p>
</li>
</ul>
<h3 id="heading-step-1-your-dockerfile-probably-just-works">Step 1: Your Dockerfile Probably Just Works</h3>
<p>This is the beautiful part—Podman uses the same OCI container format as Docker. Your existing Dockerfile should work without any changes. Here's a typical FastAPI setup:</p>
<pre><code class="lang-plaintext">FROM python:3.10-slim-buster

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir --upgrade -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
</code></pre>
<h3 id="heading-step-2-build-your-image">Step 2: Build Your Image</h3>
<p>Instead of docker build, just run:</p>
<pre><code class="lang-bash">podman build -t my-fastapi-app:latest .
</code></pre>
<p>That's it. Same flags, same behavior, same output. If you want to ease the transition, create an alias:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">alias</span> docker=podman
</code></pre>
<p>Now you can use your existing docker build commands without thinking about it.</p>
<h3 id="heading-step-3-run-your-container">Step 3: Run Your Container</h3>
<p>For development and testing:</p>
<pre><code class="lang-bash">podman run --rm -p 8000:8000 --name my-fastapi-container my-fastapi-app:latest
</code></pre>
<p>For background services:</p>
<pre><code class="lang-bash">podman run -d -p 8000:8000 --name my-fastapi-container my-fastapi-app:latest
</code></pre>
<p>Your app should be accessible at http://localhost:8000 just like before.</p>
<p><strong>Important note:</strong> <em>By default, Podman runs in rootless mode. This is a security win, but it means you can't bind directly to privileged ports (below 1024). For production, you'll want a reverse proxy anyway, so this pushes you toward better architecture.</em></p>
<h3 id="heading-step-4-production-deployment-with-systemd">Step 4: Production Deployment with Systemd</h3>
<p>This is where Podman really shines. Instead of wrestling with custom service management, generate a proper systemd unit file:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># First, make sure your container is running</span>

podman run -d -p 8000:8000 --name my-fastapi-container my-fastapi-app:latest

<span class="hljs-comment"># Generate the systemd service file</span>

mkdir -p ~/.config/systemd/user/

podman generate systemd --name my-fastapi-container &gt; ~/.config/systemd/user/my-fastapi-container.service

<span class="hljs-comment"># Enable and start the service</span>

systemctl --user daemon-reload

systemctl --user <span class="hljs-built_in">enable</span> my-fastapi-container.service

systemctl --user start my-fastapi-container.service
</code></pre>
<p>Now your FastAPI app is managed like any other system service. It'll start on boot, restart on failure, and integrate with standard Linux logging and monitoring tools.</p>
<p>For server deployments where you want the service to persist even when you're not logged in:</p>
<p>loginctl enable-linger $(whoami)</p>
<h3 id="heading-step-5-multi-service-applications-with-pods">Step 5: Multi-Service Applications with Pods</h3>
<p>If your FastAPI app needs a database or other services, Podman's pod concept is cleaner than Docker Compose for simple setups:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create a pod that shares networking</span>
podman pod create --name my-fastapi-pod -p 8000:8000 -p 5432:5432

<span class="hljs-comment"># Run your FastAPI app in the pod</span>

podman run -d --pod my-fastapi-pod --name fastapi-app my-fastapi-app:latest

<span class="hljs-comment"># Run PostgreSQL in the same pod</span>

podman run -d --pod my-fastapi-pod --name postgres-db -e POSTGRES_PASSWORD=mysecretpassword postgres:13
</code></pre>
<p>Now your FastAPI app can reach PostgreSQL at localhost:5432 because they share the same network namespace.</p>
<h3 id="heading-step-6-docker-compose-compatibility">Step 6: Docker Compose Compatibility</h3>
<p>For existing Docker Compose setups, you have options:</p>
<p><strong>Option 1:</strong> Use podman-compose as a drop-in replacement:</p>
<pre><code class="lang-bash">pip install podman-compose

podman-compose up -d
</code></pre>
<p><strong>Option 2:</strong> Convert to Kubernetes YAML for a more cloud-native approach:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Install kompose first</span>

kompose convert -f docker-compose.yml -o k8s-manifest.yaml

podman play kube k8s-manifest.yaml
</code></pre>
<p>This second option is particularly nice if you're planning to deploy to Kubernetes eventually.</p>
<p><strong>Common Gotchas and Solutions</strong></p>
<p><strong>Volume permissions:</strong> If you hit permission issues with mounted volumes, remember that rootless containers run as your user. Make sure your user owns the directories you're mounting:</p>
<pre><code class="lang-bash">chown -R $(id -un):$(id -gn) /path/to/your/data
</code></pre>
<p><strong>Legacy tooling:</strong> Some tools expect the Docker socket at /var/run/docker.sock. Podman can provide a compatible API:</p>
<pre><code class="lang-bash">systemctl --user <span class="hljs-built_in">enable</span> podman.socket

systemctl --user start podman.socket

<span class="hljs-built_in">export</span> DOCKER_HOST=unix://<span class="hljs-variable">$XDG_RUNTIME_DIR</span>/podman/podman.sock
</code></pre>
<p><strong>Performance tuning:</strong> For production workloads, you might want to tune the rootless networking stack or consider running specific containers in rootful mode for maximum performance.</p>
<p>The migration process is usually much smoother than people expect. Start with a development environment, get comfortable with the workflow differences, then gradually move production workloads. The security and operational benefits make it worth the effort.</p>
]]></content:encoded></item><item><title><![CDATA[Architecting Your Software Startup: Learning from Citadel's Monolithic Foundations]]></title><description><![CDATA[While building a software startup you must carefully consider the architectural foundation on which your future multi-billion dollar business will be built. This will profoundly influence the trajectory and either set up you for success or a great fa...]]></description><link>https://codesmash.dev/architecting-your-software-startup-learning-from-citadels-monolithic-foundations</link><guid isPermaLink="true">https://codesmash.dev/architecting-your-software-startup-learning-from-citadels-monolithic-foundations</guid><category><![CDATA[Software Engineering]]></category><category><![CDATA[monolithic architecture]]></category><category><![CDATA[monolith]]></category><category><![CDATA[Startups]]></category><dc:creator><![CDATA[Dominik Szymański]]></dc:creator><pubDate>Thu, 19 Oct 2023 21:41:01 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/spP1E4gYE9A/upload/202b92e1ec108138555887933f9c2909.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>While building a software startup you must carefully consider the architectural foundation on which your future multi-billion dollar business will be built. This will profoundly influence the trajectory and either set up you for success or a great failure. The software development landscape offers a rich variety of architectural paradigms it's worth examining the case of embracing a long-withstanding architectural marvel that is the Citadel.</p>
<p>The main purpose of Citadel is to stand as a guardian and a symbol of strength. The same attributes you look for in your software architecture. Your software needs to serve as a robust sentinel for your digital aspirations. Citadels originally were thought of as a singular structures housing numerous functions and providing a secure environment for inhabitants. In the realm of software, a monolithic architecture is often similarly designed to be cohesive, efficient, and secure.</p>
<p>So what can we learn from adopting a citadel design in software architecture? In this article, I will try to delve into the rationale for adopting citadel architecture for your software startup and explore how this approach aligns with the purpose of the Citadel: a resilient, all-encompassing fortress that stands as a beacon of stability and dependability. I will try to uncover the advantages of starting from monolithic architecture and how it can contribute to your startup's growth and success.</p>
<p>I will try to guide you through the whole journey, discuss the key principles, and bring some potential pitfalls and best practices to consider when crafting your digital citadel. After this article, you'll gain an appreciation for this design choice and you should be better equipped to make your software startup foundation solid so it can survive any earthquakes which you will experience while building your business. Just as the Citadel withstood the test of time, your software venture, architected with care and purpose, can also endure and thrive in the ever-evolving landscape of the digital world.</p>
<h2 id="heading-citadel-v1-mvp-phase">Citadel v1 (MVP phase)</h2>
<p>You are in the most bumpy phase of the startup lifecycle. You will have to face multiple crossrosroads, changes are natural and should be welcomed. That's the moment when your visionary concepts and aspirations begin to materialize into tangible digital creations. MVP requires a strong architectural foundation. By embracing the approach proposed by me, you will be able to swiftly transform your ideas into functional realities, steering your product towards innovation and quick market validation. At this phase, you should think about your software citadel as a monolithic structure that is built using battle-tested frameworks. Below you can find my justification for why you should pursue this path (paved already by companies like Shopify).</p>
<ol>
<li><p><strong>Simplicity and Speed:</strong> MVP is all about quickly testing your product ideas in the wild and learning from usage data and customer feedback. Even though it might be tempting to create a simple lambda service for some functionalities maintaining a monolithic architecture is inherently simpler compared to any distributed architecture. Monolithic architecture offers speed and agility, allowing your development team to focus on building the core features and functionalities of your product without the overhead of managing multiple services, databases, and communication protocols. This streamlined approach can significantly accelerate development, reducing time to market. Additionally onboarding new engineers will be easier - stepping into a codebase in which you can easily trace data flow will pay off in shorter onboarding periods and fewer overheads on training of a proprietary split of microservices.</p>
</li>
<li><p><strong>Cost-Effectiveness:</strong> Startups always operate with limited budgets, the monolithic approach is always much more cost-effective in the early stages. Fewer engineers will be required to deploying and maintain a product. Which means you will be able to focus your engineers towards feature development which is crucial for startups seeking to validate their business model and attract initial customers. On top of that, a monolith app can be deployed to a single instance which is always cheaper than any serverless solution.</p>
</li>
<li><p><strong>Ease of Iteration:</strong> Your team will have to rapidly iterate over user feedback and market insights. In a monolithic architecture, changes can be implemented more swiftly, as there's a single codebase to modify. This ease of iteration enables your business to respond quickly to user needs and evolving market conditions, fostering a truly agile development process.</p>
</li>
<li><p><strong>Reduced Complexity:</strong> In the early stage of lifecycle your application feature set will be relatively simple. A monolithic architecture minimizes this complexity, making it easier for developers to understand and work with the codebase. This simplicity is beneficial as it makes debugging and troubleshooting easier. Additionally, monitoring of distributed systems is complex and requires a ton of expensive tools to do it properly.</p>
</li>
<li><p><strong>Resource Efficiency:</strong> Monolith architecture will keep your operational overhead to a minimum, allowing your team to focus on validating an MVP. Managing and monitoring a distributed architecture, as well as ensuring communication and data consistency between services, can be resource-intensive.</p>
</li>
<li><p><strong>Easier Testing:</strong> During MVP phase usually you do not have a quality assurance team. Making sure that your software is reliable will require extensive testing. The cohesiveness of a single code base makes end-to-end testing easier and will result in much faster resolution of detected issues.</p>
</li>
</ol>
<h2 id="heading-citadel-v2-growth-phase">Citadel v2 (Growth phase)</h2>
<p>Citadels throughout history have shown an impressive ability to adapt and evolve in response to changing threats and requirements. Similarly, your software startup can take inspiration from this adaptability when evolving initial monolithic architecture to accommodate growth. Here's how a startup's architecture can evolve, much like citadels:</p>
<ol>
<li><p><strong>Fortification and Expansion:</strong> Because you found a product market fit you will be noticed by others (competition, more customers, and bad actors). While constantly facing changing threats, you will have to fortify and expand your software. In the early stages, a monolithic architecture may suffice for an MVP. Still, as the startup gains traction and user numbers increase, it becomes necessary to fortify the infrastructure. This can be achieved through the following steps:</p>
<ul>
<li><p><strong>Standalone services:</strong> When you find a product market fit your software should be battle-tested. Right now team already identified which modules of the system have clear boundaries and single responsibility. Usually, those modules do not require access to the full data model and communication with other modules is clear. Those are perfect candidates for smaller standalone services.</p>
</li>
<li><p><strong>Scaling for Performance:</strong> Hopefully, when user loads increase, scaling your software becomes critical. Leveraging cloud services and containerization will make horizontal scaling a breeze, ensuring that the system can handle more users and higher workloads. With modern tools like Docker and K8s, this will be a no-brainer for any DevOps engineer and will allow to effectively use resources bought from cloud providers.</p>
</li>
<li><p><strong>Data Partitioning and Replication:</strong> When your database grows and you are not able to scale app your DB instance vertically (but only when this happens) you will have to think about data partitioning (splitting one DB into smaller ones) and replication strategies (maybe different instance for reading and different for writing). This ensures data availability and performance as your user base expands.</p>
</li>
<li><p><strong>Load Balancing and Redundancy:</strong> Implement load balancers and redundancy to improve reliability and fault tolerance on any level.</p>
</li>
</ul>
</li>
<li><p><strong>Improved Security Measures:</strong> You will have to start threatening security very seriously and as citadels reinforce their defences against evolving warfare techniques, your team must bolster their security measures to protect against cyber threats. As the user base and data grow, invest in robust security practices and technologies, such as penetration testing, encryption, authentication, and regular security audits.</p>
</li>
<li><p><strong>Resource Allocation:</strong> Citadels strategically allocated resources to critical areas based on changing needs. Similarly, you as a company should allocate resources wisely. As the application evolves, it's critical that you can easily allocate engineering efforts and resources to the most critical areas, such as performance optimization, user experience enhancements, and feature development.</p>
</li>
<li><p><strong>Optimizing for User Experience:</strong> You will have to put a lot of focus into user experience and provide them comfort and shelter similar to Citadels. Gather user feedback and continually improve the application's usability, performance, and responsiveness to ensure customer satisfaction.</p>
</li>
<li><p><strong>Disaster Recovery and Resilience:</strong> Citadels were often built to withstand sieges and disasters. Similarly, startups should invest in disaster recovery plans and resilience measures to ensure business continuity in the face of unexpected outages or failures.</p>
</li>
</ol>
<h2 id="heading-final-thoughts">Final thoughts</h2>
<p>In conclusion, the monolithic approach offers a compelling choice for software startups seeking to establish a solid foundation for their digital aspirations. Its simplicity, speed, and cost-effectiveness make it an ideal option for startups in the early stages of development.</p>
<p>As startups mature and their needs evolve, they may eventually need to migrate to a more distributed architectural approach. However, the foundations laid by a monolithic architecture can provide a valuable starting point, enabling startups to build upon their successes and achieve even greater heights.</p>
<p>So, as you embark on the journey of building your software startup, carefully consider the merits of the monolithic approach. Just as the Citadel stood as a bastion of strength and resilience, a monolithic architecture can provide the foundation upon which you can build a thriving and enduring digital enterprise.</p>
<p>Remember, the choice of software architecture is not a permanent one. As your startup grows, you may need to adapt your approach. But for the early stages, the monolithic citadel offers an unyielding foundation upon which to build your dreams.</p>
]]></content:encoded></item><item><title><![CDATA[Stuck in the Past: Dealing with Old SPA Code in Open Tabs]]></title><description><![CDATA[Picture this: you've just deployed a shiny new version of your Single-Page Application (SPA) to your eager users. You've poured countless hours of development, tweaking, and testing into this upgrade, ready to unveil its exciting features and enhance...]]></description><link>https://codesmash.dev/stuck-in-the-past-dealing-with-old-spa-code-in-open-tabs</link><guid isPermaLink="true">https://codesmash.dev/stuck-in-the-past-dealing-with-old-spa-code-in-open-tabs</guid><category><![CDATA[React]]></category><category><![CDATA[spa]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[frontend]]></category><dc:creator><![CDATA[Dominik Szymański]]></dc:creator><pubDate>Thu, 15 Jun 2023 21:16:30 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1686863575930/284aa074-d093-4e0f-9e9d-e188efc9e0e0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Picture this: you've just deployed a shiny new version of your Single-Page Application (SPA) to your eager users. You've poured countless hours of development, tweaking, and testing into this upgrade, ready to unveil its exciting features and enhancements. You sit back, envisioning a seamless transition as users embrace the fresh interface and improved functionality.</p>
<p>But wait! Little did you know that lurking in the shadows of countless browsers, there's an army of users who are about to make you question the very fabric of time and software deployment. These users, blissfully unaware of the updates you've painstakingly crafted, are clicking away on their open browser tabs, oblivious to the fact that they're stuck in a digital time warp.</p>
<p>Imagine this scenario: you've just launched the latest version of your social media platform. Users excitedly log in, only to be greeted by an outdated user interface that feels like it was plucked from the dark ages of the internet. Meanwhile, in another corner of the digital realm, a user nonchalantly likes a photo of their friend's cat, blissfully unaware that a vibrant new colour scheme and sleek animations have transformed the very essence of the platform.</p>
<p>As a developer, this leaves you scratching your head, pondering the mystical realms of software deployment. How do you bridge the gap between the present and the past? How do you ensure that users seamlessly transition to the latest version of your SPA, without leaving behind a trail of outdated code and confused users?</p>
<p>In this article, we will delve into the perplexing world of managing old SPA code in open tabs. We'll explore the challenges it poses for developers, discuss the potential pitfalls, and uncover strategies to mitigate this quirk of web application development. So, strap on your seatbelts and get ready for a journey through the labyrinth of software time travel!</p>
<h2 id="heading-solution">Solution</h2>
<p>To tackle the challenge of users stuck on old SPA code in open tabs, developers have devised clever solutions. One such approach involves implementing a versioning mechanism that leverages communication between the front end and the back end. By adding a special header, aptly named 'x-app-version,' to each request sent to the API backend, developers can inform the server about the current version of the SPA being used. Upon receiving a request, the backend diligently inspects the 'x-app-version' header and compares it with the latest available version. If a mismatch is detected, the server responds with an HTTP status of 400, indicating that the user's SPA version is outdated. This prompts the front end to gracefully handle the error and guide the user to refresh their page, ensuring they receive the latest version of the application. This clever interplay between the front end and back end helps bridge the gap between old and new SPA code, allowing for a smoother transition and ensuring users are always up-to-date with the latest and greatest features.  </p>
<p>Below you will find an example of middleware written in Express.js:  </p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);
<span class="hljs-keyword">const</span> app = express();

<span class="hljs-keyword">const</span> latestAppVersion = <span class="hljs-string">'1.0.0'</span>; <span class="hljs-comment">// Replace with your latest app version</span>

app.use(<span class="hljs-function">(<span class="hljs-params">req, res, next</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> appVersion = req.headers[<span class="hljs-string">'x-app-version'</span>];

  <span class="hljs-keyword">if</span> (appVersion !== latestAppVersion) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).send(<span class="hljs-string">'Outdated SPA version. Please refresh the page.'</span>);
  }

  <span class="hljs-comment">// Proceed with processing the request for the latest version of the SPA</span>
  next();
});

<span class="hljs-comment">// Define your routes and application logic below</span>
<span class="hljs-comment">// ...</span>

app.listen(<span class="hljs-number">8080</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Server listening on port 8080...'</span>);
});
</code></pre>
<p>In this example, we define a middleware function that checks the value of the <code>x-app-version</code> header in each incoming request. If the extracted version does not match the latest version, we respond with an HTTP 400 status code and an appropriate error message. Otherwise, the middleware allows the request to proceed by calling <code>next()</code>, allowing you to define your routes and application logic below.</p>
<p>Please note that this is a simplified example to illustrate the middleware concept. You may need to adapt the code to fit your specific application structure and additional middleware requirements.</p>
<p>Here's a simple example of React code that demonstrates how you can handle the error response from the backend and redirect the user to refresh the page:</p>
<pre><code class="lang-javascript">jsxCopy codeimport React, { useEffect, useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> App = <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> [error, setError] = useState(<span class="hljs-literal">null</span>);

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-comment">// Make a request to the backend here using your preferred HTTP library (e.g., axios)</span>

    <span class="hljs-comment">// Example error response received from the backend</span>
    <span class="hljs-keyword">const</span> errorResponse = {
      <span class="hljs-attr">status</span>: <span class="hljs-number">400</span>,
      <span class="hljs-attr">message</span>: <span class="hljs-string">'Outdated SPA version. Please refresh the page.'</span>,
    };

    <span class="hljs-keyword">if</span> (errorResponse.status === <span class="hljs-number">400</span>) {
      setError(errorResponse.message);
    }
  }, []);

  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      {error ? (
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Error: {error}<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{()</span> =&gt;</span> window.location.reload()}&gt;Refresh Page<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      ) : (
        // Render your main application content here
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Welcome to My App<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      )}
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<p>In this example, we use the <code>useEffect</code> hook to simulate requesting the backend. If the error response from the backend indicates an outdated SPA version (status 400), we set the error state with the corresponding message.</p>
<p>In the component's JSX, we conditionally render an error message along with a button to refresh the page if the <code>error</code> state is not null. Clicking the "Refresh Page" button triggers the <code>window.location.reload()</code> function, which reloads the entire page, fetching the latest version of the SPA from the backend.</p>
<p>Note that this is a simplified example to demonstrate the concept. You would need to integrate this error-handling logic into your React application and adapt it to your specific needs and HTTP library.</p>
<p>The article explores the common problem faced by developers when deploying new versions of Single-Page Applications (SPAs). It begins with a clever and humorous real-life example, depicting users unknowingly stuck on outdated SPA code while interacting with the application.</p>
<h2 id="heading-summary">Summary</h2>
<p>In a world where time and technology collide, imagine unsuspecting users trapped in a digital time warp! Our article, "Stuck in the Past: Dealing with Old SPA Code in Open Tabs," takes you on a wild ride through the perplexing problem faced by developers when deploying new versions of Single-Page Applications (SPAs).</p>
<p>We start with a hilarious real-life scenario: users innocently click away on their open browser tabs, blissfully unaware that they're about to be thrust into a parallel universe of outdated code. But fear not! Our ingenious solution comes to the rescue.</p>
<p>We unveil a secret weapon: the mystical 'x-app-version' header. By wielding this powerful artefact, developers can communicate with the API backend, alerting it to the user's current SPA version. Like a time-travelling detective, the backend compares the version to the latest release. If a mismatch occurs, it unleashes an HTTP status 400, leaving the user scratching their head in confusion.</p>
<p>But wait, there's more! Our frontend hero steps in, gracefully handling the error with finesse. It gently guides the user, whispering, "Refresh thy page, dear traveller, and behold the wonders of the latest SPA version!" With a click of a button, the page refreshes, transporting the user to the cutting-edge realm of sleek designs and innovative features.</p>
<p>In this humorous and whimsical tale, we demystify the challenge of managing users stuck in the past. Our solution not only ensures a seamless transition but also saves users from the clutches of outdated code. So strap in, embrace the chaos, and join us on this entertaining journey through the twists and turns of software time travel!</p>
]]></content:encoded></item><item><title><![CDATA[Look Ma - I invented PHP!]]></title><description><![CDATA[In the ever-evolving world of web development, trends come and go like fashion fads. One such trend that has caught the attention of developers is React server components. While touted as an innovative approach, it's hard to ignore the striking simil...]]></description><link>https://codesmash.dev/look-ma-i-invented-php</link><guid isPermaLink="true">https://codesmash.dev/look-ma-i-invented-php</guid><category><![CDATA[React]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Frontend Development]]></category><category><![CDATA[frontend]]></category><dc:creator><![CDATA[Dominik Szymański]]></dc:creator><pubDate>Mon, 05 Jun 2023 08:00:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/0DJHJcpwN9Q/upload/fc6b352bce101db0ae53e039a4283272.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In the ever-evolving world of web development, trends come and go like fashion fads. One such trend that has caught the attention of developers is React server components. While touted as an innovative approach, it's hard to ignore the striking similarities to a technology that has been around for ages: PHP. Yes, you read that right. React server components, in some ways, feel like reinventing the wheel. So, put on your humour hat as we take a lighthearted look at this curious case of "Look Ma - I invented PHP!"</p>
<ol>
<li><p>The Time Traveler's Dilemma: React server components, meet PHP. PHP, meet React server components. It's like they exist in two different periods, yet share an uncanny resemblance. PHP has been powering websites since the dawn of the internet, and now React server components aim to bring server-side rendering back into the limelight. It's like inventing a time machine and realizing that you've ended up in the same era.</p>
</li>
<li><p>Revisiting the Wheel: One of the main selling points of React server components is their ability to render components on the server, delivering faster and more interactive user experiences. Sounds familiar? PHP has been doing that for years! With PHP, you can write server-side scripts that generate HTML dynamically, delivering a similar promise of faster loading times and server-side interactivity. It's like reinventing the wheel, but with a fancy new tire tread.</p>
</li>
<li><p>PHP: The Original Dynamic Duo: PHP's server-side scripting capabilities allowed developers to generate dynamic content, interact with databases, and seamlessly integrate with HTML. React server components, on the other hand, offer server-side rendering with component-based architecture. But wait, isn't that what PHP has been doing all along? It's like Batman meeting Robin, only to realize they've been fighting crime side by side all along.</p>
</li>
<li><p>A Match Made in Mashup Heaven: React server components have garnered attention due to their ability to bridge the gap between front-end and back-end developers. They allow teams to work together seamlessly, just like PHP did back in the day. PHP has a rich ecosystem of frameworks, content management systems, and libraries that have empowered developers for years. React server components, with their focus on reusability and modularity, seem to be following in PHP's footsteps.</p>
</li>
<li><p>Nostalgia, Meet the Future: React server components may have breathed new life into server-side rendering, but PHP continues to be the backbone of countless websites and applications. It's the OG scripting language that has stood the test of time. So, while React server components offer new possibilities, let's not forget the tried and tested PHP. It's like getting a shiny new toy while still cherishing your favourite childhood teddy bear.</p>
</li>
</ol>
<p>React server components, with their undeniable resemblance to PHP's server-side scripting capabilities, bring forth a sense of nostalgia and curiosity. While it's amusing to witness the parallels between the two, it's essential to consider the bigger picture. Instead of solely focusing on React server components, the React team should realign with the modern web environment and embrace the broader concept of web components.</p>
<p>Web components, with their encapsulated and reusable nature, have gained momentum as a standard for building modular and interoperable web applications. As a popular and influential player in the web development landscape, React could lead the charge in fully supporting web components. By doing so, React would position itself as a trailblazer, harmonizing with other frameworks and fostering a collaborative ecosystem.</p>
<p>React, like a special child in the classroom, possesses a unique set of skills and strengths. It has revolutionized the way we think about building user interfaces and has a vibrant community backing its every move. By embracing web components, React can harness its powers and work hand in hand with other frameworks, enhancing the overall developer experience and enabling seamless integration across diverse projects.</p>
<p>In this dynamic world of web development, the wheel will continue to turn, and trends will come and go. As developers, it's crucial to adapt, evolve, and embrace the future while cherishing the lessons learned from the past. Whether it's React server components, PHP, or the promising realm of web components, let's continue to push the boundaries of what's possible and create web experiences that delight users and developers alike.</p>
<p>So, as we bid adieu to the notion of reinventing the wheel, let's set our sights on a future where React thrives as a transformative force, embracing the modern web environment and taking web components under its wing. After all, in this ever-changing classroom of technology, it's the collective growth and progress that truly matter.</p>
]]></content:encoded></item><item><title><![CDATA[Say goodbye to Scrum and hello to Kanban!]]></title><description><![CDATA[But why?!
Measuring dev team velocity is like monitoring the pulse of a marathon runner: it tells you how fast they're going and whether they're likely to finish the race on time, but it won't help you predict if they'll stop for a snack, trip on a b...]]></description><link>https://codesmash.dev/say-goodbye-to-scrum-and-hello-to-kanban</link><guid isPermaLink="true">https://codesmash.dev/say-goodbye-to-scrum-and-hello-to-kanban</guid><category><![CDATA[management]]></category><category><![CDATA[kanban]]></category><category><![CDATA[Scrum]]></category><category><![CDATA[engineering]]></category><category><![CDATA[development]]></category><dc:creator><![CDATA[Dominik Szymański]]></dc:creator><pubDate>Sun, 16 Apr 2023 11:00:04 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1681641384540/6f87377a-e3e6-4b26-a783-69ad4ad4f91b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-but-why">But why?!</h2>
<p>Measuring dev team velocity is like monitoring the pulse of a marathon runner: it tells you how fast they're going and whether they're likely to finish the race on time, but it won't help you predict if they'll stop for a snack, trip on a banana peel, or decide to crawl on all fours just for fun. Yet, just like a marathon coach, project managers and stakeholders love to obsess over velocity charts, hoping to extract some deep insight into the team's productivity, efficiency, and sanity.</p>
<p>After all, what's more fun than watching a bunch of nerds typing furiously on their keyboards, while colourful bars and numbers dance on a screen? It's like a video game, but with fewer explosions and more coffee stains. But don't be fooled by the superficial excitement: velocity is not just a metric, it's a reflection of the team's morale, communication, skills, and culture. If the velocity is high, the team is happy and productive; if it's low, they're probably drowning in bugs, meetings, and existential questions. In other words, velocity is like the temperature of a team's soul: if it's too hot, they're burning out; if it's too cold, they're freezing in despair. So, let's dive into the wild and wacky world of measuring dev team velocity and see how it can make or break your project!</p>
<h2 id="heading-kanban-ftw">Kanban FTW!</h2>
<p>Working in Scrum always felt like being stuck in a time warp, where everything moved at a snail's pace and the world outside was changing at lightning speed. It was like trying to navigate a horse-drawn carriage on the autobahn. Sure, you could make progress, but you were constantly being overtaken by faster, more agile vehicles.</p>
<p>Scrum's rigid structure and time-boxed sprints felt limiting and artificial, like trying to fit a square peg into a round hole. It was like trying to follow a recipe for a dish you didn't even like, just because it was the "right" way to cook it.</p>
<p>In the end, I realized that Scrum just wasn't the right fit for me. I needed a methodology that was more flexible and adaptable, and that could keep up with the speed of change in the world. That's why I switched to Kanban, where everything flows smoothly and there's always room for innovation and improvement. Now, I feel like I'm driving a Ferrari on the autobahn, and I'm never looking back!</p>
<p>Choosing between Kanban and Scrum is like choosing between a leisurely stroll and a marathon. Scrum is like a marathon, with its intense sprints, constant meetings, and strict rules. It can leave you feeling exhausted and drained, wondering if it's all worth it. Kanban, on the other hand, is like a leisurely stroll, with its relaxed pace, focus on flow, and minimal meetings. It can leave you feeling refreshed and energized, ready to take on whatever challenges come your way.</p>
<p>So, if you're tired of the endless meetings and rigid structure of Scrum, why not take a stroll with Kanban? You'll have more time to enjoy the scenery and less time worrying about meeting the next deadline. Just don't forget to bring a water bottle and some comfy shoes!</p>
<h2 id="heading-measuring-dev-team-pulse-in-kanban">Measuring dev team pulse in Kanban</h2>
<h3 id="heading-lead-time">Lead time</h3>
<p>Lead time is like a rollercoaster ride at an amusement park. It's the time it takes from the moment you get in line to the moment you actually get on the ride. Just like waiting in line for a rollercoaster, lead time can feel like an eternity, but when you finally get on the ride, it's worth the wait!</p>
<p>To measure lead time using JIRA, you'll need to track the time it takes for a task to move through each stage of your Kanban board, from "To Do" to "Done." JIRA has a built-in feature called "Time in Status" that allows you to track how long a task spends in each status, so you can easily calculate the total lead time for a task.</p>
<p>To calculate lead time using JIRA, simply add up the time a task spends in each status, including any time it spends waiting in a queue, and you'll have your lead time. With JIRA, you can easily track lead time for individual tasks, as well as for your entire Kanban board, so you can identify areas for improvement and optimize your workflow.</p>
<h3 id="heading-cycle-time">Cycle time</h3>
<p>Cycle time is like a pizza delivery service. It's the time it takes for your pizza to go from the oven to your doorstep. Just like waiting for your pizza to arrive, cycle time can feel like an eternity, especially when you're hungry and craving a slice.</p>
<p>To measure cycle time using JIRA, you'll need to track the time it takes for a task to move from "In Progress" to "Done" on your Kanban board. JIRA's "Time in Status" feature can help you track this by measuring the time a task spends in each status.</p>
<p>To calculate cycle time using JIRA, simply subtract the time a task spent waiting in a queue from the total time it spent in progress, and you'll have your cycle time. With JIRA, you can track cycle time for individual tasks, as well as for your entire Kanban board, so you can optimize your workflow and get your tasks done faster than you can say "extra cheese, please!"</p>
<h3 id="heading-throughput">Throughput</h3>
<p>Throughput is like a conveyor belt at a sushi restaurant. It's the number of sushi plates that can be delivered to your table in a certain amount of time. Just like the conveyor belt at a sushi restaurant, throughput can be fast and efficient, or slow and inefficient, depending on how well your team is working together.</p>
<p>To measure throughput using JIRA, you'll need to track the number of tasks completed within a given period of time, such as a week or a month. JIRA's reporting features can help you generate reports that show you how many tasks were completed during a certain period, so you can track your team's throughput.</p>
<p>To optimize your team's throughput, you'll want to focus on improving your process and eliminating bottlenecks. Just like a sushi chef needs to keep the plates moving down the conveyor belt to keep customers happy, your team needs to keep tasks moving through your Kanban board to deliver value to your customers efficiently. So, if you want to improve your throughput, just remember to keep the sushi (or tasks) coming!</p>
<h3 id="heading-work-in-progress-limit">Work in progress limit</h3>
<p>WIP limits are like a buffet at an all-you-can-eat restaurant. They're the number of plates you're allowed to pile up on your tray at once. Just like the buffet, if you try to take on too much at once, you're likely to end up with a stomachache (or in the case of WIP limits, a backlog that's impossible to manage).</p>
<p>To implement WIP limits in JIRA, you'll need to set a maximum number of tasks that can be in progress at any given time. This helps ensure that your team doesn't take on more than they can handle, and helps prevent work from piling up in your backlog.</p>
<p>WIP limits can be a powerful tool for optimizing your workflow, but they're only effective if you stick to them. Just like at the buffet, it can be tempting to load up your tray with as much as possible, but if you do, you're likely to end up feeling overwhelmed and overburdened. So, if you want to get the most out of your WIP limits, remember to pace yourself, and only take on what you can handle!</p>
<h3 id="heading-cumulative-flow-diagram">Cumulative flow diagram</h3>
<p>Cumulative Flow Diagrams are like a fitness tracker for your team's productivity. They're the visual representation of how your team's work is flowing (or not flowing) through your workflow stages. Just like with fitness, if you want to improve your team's productivity, you need to keep track of your progress.</p>
<p>To create a Cumulative Flow Diagram in JIRA, you'll need to track the number of tasks in each workflow stage over time. This helps you identify bottlenecks and areas where your team is struggling to keep up. It's like looking at a map of your team's journey and seeing where you're getting stuck in traffic.</p>
<p>Cumulative Flow Diagrams can be a powerful tool for optimizing your workflow, but they're only effective if you use them consistently. Just like with fitness, if you only check your progress once a year, you're not going to see much improvement. So, if you want to stay on top of your team's productivity, make sure to check in regularly and use the data to make informed decisions!</p>
<h2 id="heading-summary">Summary</h2>
<p>Are you tired of feeling like your dev team is always one step behind? Do you want to improve productivity, boost morale, and get ahead of the game? Then it's time to ditch Scrum and embrace Kanban, the MVP of Agile Development. By measuring dev team velocity with metrics like lead time, cycle time, throughput, and WIP limits, and creating a Cumulative Flow Diagram to track progress, you can optimize your workflow and achieve maximum productivity. So, what are you waiting for? Say goodbye to Scrum and hello to Kanban!</p>
]]></content:encoded></item><item><title><![CDATA[Debt of Code: A Modern Tragedy]]></title><description><![CDATA[Introduction
Team Leader: A skilled and experienced engineering leader who understands the importance of addressing technical debt and is determined to convince business management to allocate time and resources for the task.
Developer 1: A passionat...]]></description><link>https://codesmash.dev/debt-of-code-a-modern-tragedy</link><guid isPermaLink="true">https://codesmash.dev/debt-of-code-a-modern-tragedy</guid><category><![CDATA[technical-debt]]></category><category><![CDATA[management]]></category><category><![CDATA[leadership]]></category><category><![CDATA[leader]]></category><dc:creator><![CDATA[Dominik Szymański]]></dc:creator><pubDate>Sun, 09 Apr 2023 11:00:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1680437671584/3e40cbef-6fa4-4d7a-b5e2-d718e254eeb8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p><strong>Team Leader</strong>: A skilled and experienced engineering leader who understands the importance of addressing technical debt and is determined to convince business management to allocate time and resources for the task.</p>
<p><strong>Developer 1</strong>: A passionate and detail-oriented developer who is committed to delivering high-quality software but has been frustrated by the technical debt that has accumulated over time.</p>
<p><strong>Developer 2</strong>: A hard-working and dedicated developer who is always looking for ways to improve their skills and make meaningful contributions to the team.</p>
<p><strong>Business Manager</strong>: A results-driven manager who is focused on the bottom line and is hesitant to allocate time and resources for technical debt when there are other pressing business needs. However, they are ultimately convinced by the team leader and recognize the importance of addressing technical debt for the long-term success of the company.</p>
<h2 id="heading-act-1-a-developers-dilemma">Act 1: A Developer's Dilemma</h2>
<p><strong>Team Leader</strong>: Hey guys, I wanted to talk to you about the technical debt that's been piling up.</p>
<p><strong>Developer 1</strong>: Yeah, it's really starting to slow us down. We keep encountering the same bugs and issues over and over again.</p>
<p><strong>Developer 2</strong>: And every time we try to fix something, we end up uncovering more problems.</p>
<p><strong>Team Leader</strong>: I know, it's frustrating. But I've been trying to talk to the business managers about this, and they keep pushing us to focus on new features.</p>
<p><strong>Developer 1</strong>: But if we don't address the technical debt, it's only going to get worse. It's like a never-ending cycle.</p>
<p><strong>Developer 2</strong>: And it's making it much harder to develop new features. We're spending more time fixing problems than actually developing new code.</p>
<p><strong>Team Leader</strong>: I completely understand your frustrations. And I've been trying to communicate this to the business managers, but they don't seem to understand the impact it's having on our development process.</p>
<p><strong>Developer 1</strong>: Can we show them examples of other companies that have suffered due to technical debt?</p>
<p><strong>Team Leader</strong>: That's a good idea. We can show them how technical debt can lead to major problems and even cause a company to fail.</p>
<p><strong>Developer 2</strong>: And we can also show them how addressing technical debt can lead to faster development times, fewer bugs, and easier maintenance.</p>
<p><strong>Team Leader</strong>: Yes, we need to find a way to communicate the importance of addressing technical debt in a way that they understand.</p>
<p><strong>Developer 1</strong>: But what if they still don't listen? What if they keep pushing us to focus on new features?</p>
<p><strong>Team Leader</strong>: We need to be persistent. We can't just give up and ignore the technical debt. We need to keep communicating the importance of addressing it, and we need to work together to find a solution that works for everyone.</p>
<p><strong>Developer 2</strong>: I just hope they start listening soon. It's really starting to affect our work and morale.</p>
<p><strong>Team Leader</strong>: I know, but we can't let our frustration get in the way of finding a solution. We need to keep fighting for what we know is right, and eventually, they will listen.</p>
<h3 id="heading-stasimon">Stasimon</h3>
<p><strong>Developers</strong>:</p>
<p>Our code is clean, our logic sound,</p>
<p>But technical debt is all around.</p>
<p>We need to fix it, we need the time,</p>
<p>To make our software truly sublime.</p>
<p><strong>Team Leader</strong>:</p>
<p>I hear your concerns, I know your pain,</p>
<p>But business managers are hard to train.</p>
<p>We'll make our case, we'll plead our cause,</p>
<p>And show them why it's worth the pause.</p>
<p>Together we'll fight, and together we'll win,</p>
<p>Our software's future we will begin,</p>
<p>With a solid foundation, a debt-free start,</p>
<p>And a product that truly sets us apart.</p>
<h2 id="heading-act-2-a-clash-of-priorities">Act 2: A Clash of Priorities</h2>
<p><strong>Team Leader</strong>: Hi, I'd like to talk to you about the technical debt that our engineering team has accrued over the years.</p>
<p><strong>Business Management</strong>: Technical debt? What is that exactly?</p>
<p><strong>Team Leader</strong>: Technical debt refers to the cost of maintaining and fixing code that was not developed properly in the first place. It is a problem that accumulates over time if not addressed properly.</p>
<p><strong>Business Management</strong>: Okay, I think I understand. But why is this such a big deal?</p>
<p><strong>Team Leader</strong>: Well, technical debt can cause major problems down the road. For example, do you remember the fall of Knight Capital? They lost $440 million in a single day due to a technical glitch that was caused by unaddressed technical debt. And do you remember the software issue with the Patriots? It cost the lives of soldiers.</p>
<p><strong>Business Management</strong>: Hmm, that is concerning. But what can we do about it?</p>
<p><strong>Team Leader</strong>: We need to allocate some time for our engineering team to address the technical debt. If we don't, it will only get worse and the cost of fixing it will only increase.</p>
<p><strong>Business Management</strong>: But we have other priorities that we need to focus on. We don't have the time or resources to address technical debt right now.</p>
<p><strong>Team Leader</strong>: I understand that, but we need to prioritize this issue. If we don't, it will only become more costly and time-consuming to fix down the road. It's like a car that needs an oil change. If you don't change the oil regularly, the engine will eventually break down and it will be much more expensive to fix.</p>
<p><strong>Business Management</strong>: Okay, that makes sense. But we've been hearing about technical debt for a while now, and we haven't seen any major problems yet. Why should we allocate resources to address it now?</p>
<p><strong>Team Leader</strong>: The longer we wait, the more expensive it will be to fix. And even if we haven't seen any major problems yet, technical debt is still affecting our development times, causing more bugs, and making maintenance more difficult. We need to address this issue before it causes major problems.</p>
<p><strong>Business Management</strong>: I understand your point, but how can we be sure that addressing technical debt will actually save us time and money in the long run?</p>
<p><strong>Team Leader</strong>: There have been many studies that have shown that addressing technical debt can lead to faster development times, fewer bugs, and easier maintenance. And as I mentioned before, if we don't address this issue now, it will only become more costly and time-consuming to fix down the road.</p>
<p><strong>Business Management</strong>: Okay, I see your point. But can we allocate less time to this issue? 20% of our engineering team's time seems like a lot.</p>
<p><strong>Team Leader</strong>: We need to allocate enough time to address the issue properly. 20% is an estimate, but we can work together to come up with a more specific plan that will allow us to address the issue while still meeting our other priorities.</p>
<p><strong>Business Management</strong>: Alright, I can see that this is an important issue that we need to address. Let's work together to come up with a plan that will allow us to allocate enough resources to address technical debt while still meeting our other priorities.</p>
<p><strong>Team Leader</strong>: Thank you. I think this is a critical issue that we need to address sooner rather than later. By addressing technical debt, we can prevent major problems down the road and stay competitive in the market.</p>
<h3 id="heading-stasimon-1">Stasimon</h3>
<p><strong>Business Manager</strong>:</p>
<p>I hear your plea, I understand,</p>
<p>The importance of addressing technical debt in our land.</p>
<p>Our company's future is on the line,</p>
<p>And technical debt will only cause us to decline.</p>
<p><strong>Team Leader</strong>:</p>
<p>I appreciate your willingness to hear,</p>
<p>Our concerns, our issues, our need to steer,</p>
<p>Our software in the right direction,</p>
<p>With technical debt-free as our main connection.</p>
<p><strong>Business Manager</strong>:</p>
<p>I trust your expertise, your knowledge, your skills,</p>
<p>To address our technical debt with minimal spills.</p>
<p>Our company's future is bright, and it's all thanks to you,</p>
<p>The team that's strong, that's dedicated and true.</p>
<h2 id="heading-act-3-the-triumph-of-common-sense">Act 3: The Triumph of common sense</h2>
<p><strong>Team Leader</strong>: Hey guys, I just wanted to say how proud I am of all of us. We've really made a difference by addressing our technical debt.</p>
<p><strong>Developer 1</strong>: Yeah, things have been so much smoother since we've been able to tackle those lingering issues.</p>
<p><strong>Developer 2</strong>: And we're able to develop new features so much faster now that we're not constantly fixing bugs.</p>
<p><strong>Business Manager</strong>: And it's not just the development team that's noticed. Our customers have been happier with the product and we've seen an increase in sales.</p>
<p><strong>Team Leader</strong>: Exactly. Addressing technical debt was the right thing to do, and it's really paid off.</p>
<p><strong>Developer 1</strong>: I'm just glad we were able to make such a big impact.</p>
<p><strong>Developer 2</strong>: And it's really made me feel more fulfilled in my work. It's nice to see the positive impact of what we do.</p>
<p><strong>Business Manager</strong>: I completely agree. It's clear that addressing technical debt was a smart business decision.</p>
<p><strong>Team Leader</strong>: Well, we need to make sure that we don't fall back into old habits. We need to keep addressing technical debt as it comes up and make sure that we're always improving our processes.</p>
<p><strong>Developer 1</strong>: Sounds good to me. I think we're all on the same page now.</p>
<p><strong>Developer 2</strong>: Yeah, we couldn't have done it without your leadership.</p>
<p><strong>Business Manager</strong>: And we couldn't have done it without your hard work and dedication. Thanks for making such a big difference for our company.</p>
<p><strong>Team Leader</strong>: It was my pleasure. Let's keep making a difference together.</p>
<h3 id="heading-stasimon-2">Stasimon</h3>
<p><strong>Team Leader:</strong></p>
<p>The burden lifted, the path now clear,</p>
<p>Our hard work paid off, with no more fear.</p>
<p>With technical debt finally slain,</p>
<p>We're ready for whatever comes our way again.</p>
<p><strong>Developer 1:</strong></p>
<p>The code is cleaner, the bugs all gone,</p>
<p>Our product's better, it won't be long.</p>
<p>Before our customers start to see</p>
<p>The benefits of our technical debt victory.</p>
<p><strong>Developer 2:</strong></p>
<p>I feel fulfilled, I feel alive,</p>
<p>Our work no longer seems like a strife.</p>
<p>With technical debt in the past,</p>
<p>We can move forward and grow at last.</p>
<p><strong>Business Manager:</strong></p>
<p>Our profits rising, our customers pleased,</p>
<p>Our future secure, our growth increased.</p>
<p>With technical debt defeated at last,</p>
<p>Our company's future has been cast.</p>
<p><strong>Everyone</strong>:</p>
<p>Together we fought, and together we won,</p>
<p>With technical debt gone, our work is fun.</p>
<p>Let's keep this momentum, let's keep this pace,</p>
<p>And secure our future for the whole human race.</p>
]]></content:encoded></item><item><title><![CDATA[Why Refactoring Your Codebase Is Like Flossing Your Teeth (And Why You Should Be Doing It More Often)]]></title><description><![CDATA[As a team leader with over 10 years of experience in the field, I can tell you that the importance of continuous refactoring of a codebase cannot be overstated. I like to think of code refactoring as akin to flossing your teeth - sure, you could skip...]]></description><link>https://codesmash.dev/why-refactoring-your-codebase-is-like-flossing-your-teeth-and-why-you-should-be-doing-it-more-often</link><guid isPermaLink="true">https://codesmash.dev/why-refactoring-your-codebase-is-like-flossing-your-teeth-and-why-you-should-be-doing-it-more-often</guid><category><![CDATA[leadership]]></category><category><![CDATA[refactoring]]></category><category><![CDATA[code refactoring]]></category><category><![CDATA[lead]]></category><dc:creator><![CDATA[Dominik Szymański]]></dc:creator><pubDate>Sun, 02 Apr 2023 10:53:23 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1680432589209/f189095f-69a4-41dd-a841-4f106b857dde.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a team leader with over 10 years of experience in the field, I can tell you that the importance of continuous refactoring of a codebase cannot be overstated. I like to think of code refactoring as akin to flossing your teeth - sure, you could skip it and everything might be okay for a while, but eventually, you're going to end up with a mouthful of cavities and a whole lot of pain.</p>
<p>But why is refactoring so important, you ask? Well, let me give you a few examples:</p>
<h3 id="heading-code-that-isnt-regularly-refactored-can-become-a-breeding-ground-for-bugs-and-technical-debt">Code that isn't regularly refactored can become a breeding ground for bugs and technical debt.</h3>
<p>Imagine a house that hasn't been cleaned in months. It might look okay on the surface, but eventually, you're going to start seeing cobwebs in the corners and dust bunnies under the couch. In the same way, code that isn't regularly cleaned up can become a breeding ground for bugs and technical debt. And just like that dirty house, the longer you leave it, the harder it is to clean up.</p>
<h3 id="heading-refactoring-will-help-your-team-scale">Refactoring will help your team scale.</h3>
<p>Imagine you're starting a new job as a software developer. You're excited to get started and eager to impress your new colleagues. You sit down at your desk, ready to dive into your first task, and you're presented with a codebase that looks like it was written in ancient hieroglyphics. The variable names are cryptic, the code is convoluted, and you have no idea what any of it does.</p>
<p>It's like walking into a stranger's house and being asked to find the bathroom without any guidance - it's confusing, overwhelming, and a little bit scary.</p>
<p>Now imagine that instead of being handed a mess of code, you're given a codebase that's well-organized, easy to navigate, and intuitive to work with. It's like walking into a friend's house and being welcomed with open arms - it's comfortable, inviting, and makes you feel at home.</p>
<p>That's the power of refactoring. When code is regularly refactored and cleaned up, it becomes easier for new joiners to get up to speed and start contributing to the team. Instead of feeling like they're wading through a sea of spaghetti code, they can dive in and start making meaningful contributions right away.</p>
<p>So if you're a team leader, think about your new joiners. Don't subject them to a codebase that looks like it was written in an alien language. Instead, make refactoring a priority and create a codebase that's welcoming, easy to navigate, and intuitive to work with. Your new joiners - and your entire team - will thank you for it. Refactoring can save you time and headaches in the long run.</p>
<p>Think of refactoring as investing in the future of your codebase. Sure, it might take a little extra time now to clean things up, but by doing so, you can avoid a whole lot of headaches down the line. And trust me, there's nothing more frustrating than spending hours trying to track down a bug in messy, unrefactored code.</p>
<p>Now, I know what you're thinking - "But wait, isn't refactoring expensive and time-consuming?" And the answer is yes, it can be. But the truth is, not refactoring can be even more expensive and time-consuming in the long run. And as a team leader, it's your job to make sure your team is working efficiently and effectively.</p>
<h2 id="heading-refactor-or-regret-how-to-keep-your-team-from-drowning-in-a-sea-of-spaghetti-code">Refactor or Regret: How to Keep Your Team from Drowning in a Sea of Spaghetti Code!</h2>
<h3 id="heading-lead-by-example">Lead by example.</h3>
<p>Being a team leader is like being a father. Just like a father takes care of his household, a team leader takes care of their codebase. And just like a father wouldn't let their house fall into disarray, a team leader shouldn't let their codebase become a messy, disorganized disaster.</p>
<p>Think of your codebase as your home. Just as you wouldn't let your dishes pile up in the sink or your laundry pile up on the floor, you shouldn't let your code become cluttered with unnecessary comments, redundant code, or poorly named variables.</p>
<p>And just like a father might teach their children the importance of cleaning up after themselves, you should encourage your team members to take ownership of their code and regularly refactor it to keep things running smoothly.</p>
<p>So next time you're feeling overwhelmed by your messy codebase, just remember - being a team leader is like being a father. And just like a good father takes care of his household, a good team leader takes care of their codebase. So roll up your sleeves, grab your tool belt, and start refactoring like the master of the household that you are.</p>
<h3 id="heading-schedule-regular-refactoring-time">Schedule regular refactoring time.</h3>
<p>One of the best ways to make sure refactoring happens is to schedule regular time for it. This could be a weekly refactoring session, or even just a few hours set aside each sprint. Make sure everyone on the team knows when refactoring time is happening, and encourage them to use that time to clean things up.</p>
<p>As a team leader, it's your responsibility to ensure that your codebase is well-maintained and organized. Just as a father might set aside time each week for chores like vacuuming or dusting, you should set aside time each sprint for refactoring and cleaning up your codebase.</p>
<h3 id="heading-make-refactoring-a-part-of-your-definition-of-done">Make refactoring a part of your definition of done.</h3>
<p>Imagine you have a pet. Let's say it's a dog named Guido. Guido is a loyal and loving companion, but he's also a bit of a mess. He sheds everywhere, he chews on everything, and he leaves muddy paw prints all over the house. But despite all of his flaws, you love Guido just the way he is.</p>
<p>Now, imagine that Guido is a codebase. Instead of shedding fur and leaving muddy paw prints, the codebase is cluttered with unnecessary code and confusing naming conventions. But just like you love Guido despite his messiness, you might feel like you love your codebase despite its flaws.</p>
<p>But here's the thing: just as you wouldn't let Guido run wild and destroy your house, you shouldn't let your codebase run wild and become a breeding ground for bugs and technical debt. And just as you wouldn't consider Guido well-behaved unless he was trained to behave properly, you shouldn't consider your codebase well-written unless it's regularly refactored and cleaned up.</p>
<p>That's why refactoring should be a part of the Definition of Done. Just as you wouldn't consider a task complete until Guido had been walked and fed and his toys had been put away, you shouldn't consider a user story complete until the code has been refactored and cleaned up.</p>
<p>So the next time you're tempted to let your codebase run wild like a mischievous pet, just remember: refactoring is the key to keeping things under control. Make it a part of your Definition of Done, and you'll be well on your way to a well-trained, well-behaved codebase - just like Guido.</p>
<h2 id="heading-just-do-it">Just do it!</h2>
<p>Now, I know what you're thinking - "Okay, all of this sounds great in theory, but what about in practice?" And the truth is, continuous refactoring isn't always easy. But just like flossing your teeth, it's something that needs to be done if you want to avoid long-term pain and discomfort.</p>
<p>So if you're not already making refactoring a priority for your team, now is the time to start. Trust me, your future self (and your codebase) will thank you.</p>
]]></content:encoded></item><item><title><![CDATA[Do you know how JavaScript manages memory?]]></title><description><![CDATA[When I was studying one of the hardest things in programming was memory management. In the vast majority of low-level languages (which you should at least briefly learn if you plan to boost your computer science understanding), memory is managed manu...]]></description><link>https://codesmash.dev/do-you-know-how-javascript-manages-memory</link><guid isPermaLink="true">https://codesmash.dev/do-you-know-how-javascript-manages-memory</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Node.js]]></category><dc:creator><![CDATA[Dominik Szymański]]></dc:creator><pubDate>Tue, 17 Jan 2023 17:49:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/t0SlmanfFcg/upload/e7ee3949176db2cd9a6c0bb0d6af427b.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When I was studying one of the hardest things in programming was memory management. In the vast majority of low-level languages (which you should at least briefly learn if you plan to boost your computer science understanding), memory is managed manually by a developer. In C++ you need to use <code>malloc</code> function to allocate something in memory. Then if you are not using it anymore you need to invoke <code>free</code> function, otherwise your program will use this memory till it runs.</p>
<p>In JavaScript, on the other hand, memory is managed automatically. The developer does not have to think about explicit memory allocation and memory management is taken care of automatically by the JS engine. In this article, I will try to explain how this <em>magic</em> is implemented in the JS engine.</p>
<h2 id="heading-the-heap">The Heap</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1673975723913/02f9135e-9980-4cc0-8e69-41183041bb13.png" alt class="image--center mx-auto" /></p>
<p>In JavaScript, the memory heap is the region of memory where objects are stored. The heap is managed by the garbage collector, which uses a data structure called the "memory block" to manage the memory.</p>
<p>A memory block is a contiguous region of memory that is used to store an object. Each memory block has a header that contains information about the object, such as its size and type. The memory block also contains the actual data of the object. When an object is created, the JavaScript runtime creates a new memory block on the heap and initializes it with the object's data.</p>
<p>As I've mentioned earlier memory is dynamically allocated during runtime. When an object is created, memory is allocated for it on the heap. When an object is no longer used, the garbage collector will mark it as eligible for collection using the "mark and sweep" algorithm.</p>
<h2 id="heading-mark-and-sweep-algorithm">Mark and sweep algorithm</h2>
<p>This algorithm is used by JS engine to identify and free up memory that is no longer used. This is a two-step process: mark and sweep (surprise!).</p>
<h3 id="heading-mark-phase">Mark phase</h3>
<p>During this phase, the GC scans through the memory and identifies all objects that are stilll used. Those which are still in use are marked as "live" and memory will not be freed up. The GC is usually starting from the global object and traverses through memory (which from a data structure perspective is a graph), any reachable object is marked as "live" during this phase.</p>
<p>Here is an example of how the mark phase works in practice:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> father = { <span class="hljs-attr">name</span>: <span class="hljs-string">"Odin"</span> };
<span class="hljs-keyword">let</span> son = { <span class="hljs-attr">name</span>: <span class="hljs-string">"Thor"</span> };

father.child = son;

<span class="hljs-comment">// If you run the mark phase of GC</span>
<span class="hljs-comment">// both objects will be marked as "live"</span>
</code></pre>
<p>In this example, we create two objects <code>father</code> and <code>son</code> and assign <code>son</code> to a property of <code>father</code>. The mark phase of the garbage collector will start with the global object, find <code>father</code> and <code>son</code> and mark them as "live" objects as they are reachable from the global object.</p>
<h3 id="heading-sweep-phase">Sweep phase</h3>
<p>Once the mark phase is complete, the garbage collector moves on to the sweep phase. During the sweep phase, the garbage collector goes through the memory and frees up any objects that are not marked as "live."</p>
<p>Here is an example of how the sweep phase works in practice:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> father = { <span class="hljs-attr">name</span>: <span class="hljs-string">"Odin"</span> };
<span class="hljs-keyword">let</span> son = { <span class="hljs-attr">name</span>: <span class="hljs-string">"Thor"</span> };

father.child = son;

father.child = <span class="hljs-literal">null</span>;

<span class="hljs-comment">// If you run the mark phase of GC</span>
<span class="hljs-comment">// the memory block conatining son object will be freed up</span>
</code></pre>
<p>In this example, we create two objects <code>father</code> and <code>son</code> and assign <code>son</code> to a property of <code>father</code>. Then we remove the reference to <code>son</code> by setting the property to <code>null</code>. At this point, <code>son</code> is no longer reachable and the sweep phase of the garbage collector will go through the memory heap, find the son and free up the memory allocated to it.</p>
<p>Historically JS engines were using reference counting as a mechanism to check if object is "live" or not. But in the browser environment, it was very easy to create a code that will result in a memory leak.</p>
<h2 id="heading-garbage-collection">Garbage collection</h2>
<p>In JavaScript, garbage collection is typically performed in a separate thread from the main event loop. This means that garbage collection will not block the main event loop and should not cause significant pauses or delays in the program's execution.</p>
<p>However, there are some cases where garbage collection can cause a brief pause in the program's execution. This can happen when the garbage collector needs to perform a full "stop-the-world" collection, which stops all program execution to perform the collection. This type of collection is usually performed when the program's memory usage exceeds a certain threshold.</p>
<p>In addition, if the garbage collection process takes too long, it can cause a delay in the program's execution. This is especially true if the program's memory usage is very high and the garbage collector needs to go through a large amount of memory to free up memory.</p>
<p>To minimize the impact of garbage collection on the program's execution, modern JavaScript engines employ techniques such as concurrent marking and incremental marking. These techniques allow the garbage collector to run in parallel with the JavaScript execution thread, which can significantly reduce the amount of time the JavaScript execution thread is paused.</p>
<p>The frequency at which the garbage collector runs in a JavaScript engine can vary depending on the specific engine and the environment in which it is running. In general, the garbage collector runs periodically in the background, trying to free up memory that is no longer being used.</p>
<p>In some JavaScript engines, the garbage collector runs on a fixed schedule, such as every few seconds or minutes. In other engines, the garbage collector runs more frequently, such as after a certain number of object allocations or deallocations.</p>
<p>Additionally, the garbage collector may also be triggered to run in response to certain events, such as when the program's memory usage exceeds a certain threshold or when the JavaScript execution thread is idle.</p>
<p>In general, the JavaScript engine takes care of the garbage collection process, developers do not have to trigger it manually. However, you can use the <code>global.gc()</code> in Node.js to trigger the garbage collection manually.</p>
]]></content:encoded></item><item><title><![CDATA[Common pitfalls to avoid when implementing a frontend project]]></title><description><![CDATA[Implementing a frontend project can be a challenging and time-consuming process, but it can also be incredibly rewarding when done correctly. However, there are several pitfalls that developers often fall into that can cause problems and delays. In t...]]></description><link>https://codesmash.dev/common-pitfalls-to-avoid-when-implementing-a-frontend-project</link><guid isPermaLink="true">https://codesmash.dev/common-pitfalls-to-avoid-when-implementing-a-frontend-project</guid><category><![CDATA[Frontend Development]]></category><category><![CDATA[frontend]]></category><category><![CDATA[management]]></category><category><![CDATA[planning]]></category><dc:creator><![CDATA[Dominik Szymański]]></dc:creator><pubDate>Thu, 22 Dec 2022 20:40:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/e14588adf7d93cd55fbe372d8fc6c977.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Implementing a frontend project can be a challenging and time-consuming process, but it can also be incredibly rewarding when done correctly. However, there are several pitfalls that developers often fall into that can cause problems and delays. In this article, we'll discuss some common pitfalls to avoid when implementing a frontend project to help ensure that your project is a success.</p>
<ol>
<li><p>Failing to properly plan and scope the project: It's essential to take the time to properly plan and scope your project before you start coding. This includes defining the project's goals, identifying the target audience, and determining the necessary features and functionality. Without a clear plan, you may end up with a project that doesn't meet the needs of your users or that takes longer to complete than expected.</p>
</li>
<li><p>Ignoring user experience: User experience (UX) is crucial when it comes to frontend development. Your users should be able to easily navigate your website or application and find what they're looking for. If the UX is poor, you'll likely see a high bounce rate and low engagement. Make sure to spend time testing and refining the UX to ensure that it meets the needs of your users.</p>
</li>
<li><p>Not paying attention to performance: Performance is another important factor to consider when implementing a frontend project. If your website or application is slow to load or unresponsive, users are likely to leave and go to a competitor. Make sure to optimize your code and use tools like web performance testing to identify and fix any performance issues.</p>
</li>
<li><p>Not testing across devices and browsers: It's essential to test your project on a variety of devices and browsers to ensure that it functions correctly and looks good on all of them. Many users access the web from different devices and browsers, and it's important to ensure that your project is accessible to all of them.</p>
</li>
<li><p>Not considering accessibility: Accessibility is the practice of making your website or application usable by as many people as possible, including those with disabilities. This includes things like making sure that your site is readable by screen readers and that it's easy to navigate using a keyboard. Failing to consider accessibility can exclude a significant portion of your potential user base and is generally considered poor practice.</p>
</li>
<li><p>Not following best practices: There are many best practices in frontend development that you should follow to ensure that your project is well-designed, maintainable, and scalable. This includes things like using a consistent style guide, properly organizing your code, and following coding standards. Ignoring these best practices can lead to a project that is difficult to maintain and update.</p>
</li>
</ol>
<p>In conclusion, there are several common pitfalls to avoid when implementing a frontend project. Proper planning, paying attention to UX and performance, testing across devices and browsers, considering accessibility, and following best practices are all essential for a successful project. By keeping these things in mind, you can avoid common mistakes and create a high-quality frontend project that meets the needs of your users.</p>
]]></content:encoded></item><item><title><![CDATA[Best practices for managing a team of frontend developers]]></title><description><![CDATA[As a frontend tech lead, managing a team of developers can be a challenging but rewarding experience. In order to ensure the success of your team and the projects they work on, it's important to establish a set of best practices for managing their wo...]]></description><link>https://codesmash.dev/best-practices-for-managing-a-team-of-frontend-developers</link><guid isPermaLink="true">https://codesmash.dev/best-practices-for-managing-a-team-of-frontend-developers</guid><category><![CDATA[management]]></category><category><![CDATA[leadership]]></category><category><![CDATA[leader]]></category><category><![CDATA[technology]]></category><dc:creator><![CDATA[Dominik Szymański]]></dc:creator><pubDate>Mon, 12 Dec 2022 19:00:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1670269280680/Z6BEbIUVE.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a frontend tech lead, managing a team of developers can be a challenging but rewarding experience. In order to ensure the success of your team and the projects they work on, it's important to establish a set of best practices for managing their work.</p>
<p>One key practice to implement is setting clear goals and expectations for each team member. This means defining the roles and responsibilities of each team member, as well as establishing individual and team-wide performance metrics. By setting clear expectations, you can help your team members understand their role in the project and what is expected of them. </p>
<p>Another important practice is to provide regular and constructive feedback to your team members. This can help to identify and address any issues or challenges they may be facing, and can also serve as a motivator for continued growth and improvement. Regular check-ins and one-on-one meetings can be effective for providing feedback and support to individual team members.</p>
<p>In addition to providing support and guidance to your team, it's also important to empower them to take ownership of their work. This can mean providing them with the autonomy to make decisions and solve problems on their own, as well as offering opportunities for professional development and growth. By fostering a culture of ownership and empowerment, you can help your team members feel invested in the success of the project and motivated to do their best work.</p>
<p>Another crucial aspect of managing a team of front end developers is staying up to date with the latest technologies and best practices in the field. This can involve attending conferences and workshops, reading industry blogs and publications, and staying active in online communities and forums. By staying informed and sharing your knowledge with your team, you can help to ensure that they are using the most effective and efficient tools and techniques for their work.</p>
<p>Overall, the key to effectively managing a team of frontend developers is to establish clear goals and expectations, provide regular feedback and support, empower your team members, and stay informed about the latest developments in the field. By implementing these best practices, you can help your team to achieve success and drive the growth and evolution of your organization's frontend capabilities.</p>
]]></content:encoded></item><item><title><![CDATA[The role of the frontend technical lead in agile development methodologies]]></title><description><![CDATA[Who is a front-end technical leader?
A front-end technical leader is a role within an organization that is responsible for overseeing and steering the development of the front-end part of a project. This will usually involve managing a team of front-...]]></description><link>https://codesmash.dev/the-role-of-the-frontend-technical-lead-in-agile-development-methodologies</link><guid isPermaLink="true">https://codesmash.dev/the-role-of-the-frontend-technical-lead-in-agile-development-methodologies</guid><category><![CDATA[General Programming]]></category><category><![CDATA[leadership]]></category><category><![CDATA[leader]]></category><category><![CDATA[tech leadership]]></category><dc:creator><![CDATA[Dominik Szymański]]></dc:creator><pubDate>Sun, 04 Dec 2022 21:39:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1670188042399/TLh8RYsHxN.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-who-is-a-front-end-technical-leader">Who is a front-end technical leader?</h1>
<p>A front-end technical leader is a role within an organization that is responsible for overseeing and steering the development of the front-end part of a project. This will usually involve managing a team of front-end developers, coordinating their work, and ensuring that the front end is implemented in a high-quality and efficient manner. The front-end tech lead is also responsible for staying up to date with the latest technologies and best practices in the field, and for providing guidance and support to the team. In addition to these technical responsibilities, a leader may also be involved in strategic planning and decision-making for the project. Effective communication and collaboration are essential for this role. In general, the role of the front-end leader is to ensure the success of the front end development effort and support the growth and evolution of the team's front end capabilities.</p>
<h1 id="heading-frontend-leader-in-an-agile-development-environment">Frontend leader in an agile development environment</h1>
<p>In an agile development methodology, the technical leader is responsible for working closely with the product owner and other key stakeholders to understand the requirements and goals of the project. This involves defining the scope of the project and breaking it down into smaller, manageable units of work. The leader is responsible for working with the team to estimate the effort required to complete each user story and prioritize them accordingly.</p>
<p>Once the user stories have been defined and prioritized, the frontend tech lead is responsible for coordinating the work of the frontend team to ensure that the user stories are completed on time and to a high standard. This involves assigning tasks to team members, monitoring their progress, and providing support and guidance as needed. The frontend tech lead is also responsible for facilitating regular meetings with the team, such as daily stand-ups and sprint planning sessions, to ensure that everyone is on track and that any potential issues or challenges are addressed on time.</p>
<h1 id="heading-technical-part-of-the-role-in-the-agile-environment">Technical part of the role in the agile environment</h1>
<p>In addition to coordinating the work of the front end team, the front-end tech leader is also responsible for managing the team's technical infrastructure. This will include setting up and maintaining version control systems, continuous integration and deployment processes, and other tools and technologies that are needed to support the team's work. The front-end tech lead is also responsible for ensuring that the team has the necessary tools and resources to be effective, such as access to the latest technologies and libraries, and providing training and support as needed.</p>
<p>Another important role of the front-end tech lead in an agile development environment is to foster a culture of collaboration and continuous improvement within the team. This can involve encouraging open communication and collaboration, facilitating knowledge sharing and mentoring, and promoting a learning culture within the team. By fostering a positive and supportive team environment, the frontend tech lead can help to ensure that the team can work effectively together and continuously improve their skills and capabilities. It's a technical leader's responsibility to ensure that the development team has enough time to learn and address technical debt on the regular basis.</p>
<h1 id="heading-summary">Summary</h1>
<p>Being a technical leader is a challenging but rewarding role. It requires a combination of technical expertise, leadership and management skills, and the ability to stay up to date with the latest technologies and best practices. By successfully meeting these challenges, a technical leader can help to ensure the success of the team and the projects they work on.</p>
<p>In conclusion, the role of the front-end tech lead in an agile development environment is crucial to the success of the project and the team. The leader is responsible for coordinating the work of the front end team, managing the team's technical infrastructure, and fostering a culture of collaboration and continuous improvement. By effectively fulfilling these responsibilities, the front-end tech lead can help to ensure the success of the project and the growth and evolution of the team's front end capabilities.</p>
]]></content:encoded></item><item><title><![CDATA[Spell-Jacking is a new browser vulnerability]]></title><description><![CDATA[Recently Otto-JS published a surprising finding. If your customer (or what's even worse you) enabled enhanced type checking it will result in sending passwords (if revealed) to their servers in plain text. More details about this vulnerability can be...]]></description><link>https://codesmash.dev/spell-jacking-is-a-new-browser-vulnerability</link><guid isPermaLink="true">https://codesmash.dev/spell-jacking-is-a-new-browser-vulnerability</guid><category><![CDATA[Security]]></category><category><![CDATA[Browsers]]></category><category><![CDATA[web application]]></category><dc:creator><![CDATA[Dominik Szymański]]></dc:creator><pubDate>Tue, 20 Sep 2022 19:32:03 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/unsplash/j7mGBT2hyM8/upload/v1663702189662/m4Z-Tx7j9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Recently Otto-JS published a surprising finding. If your customer (or what's even worse you) enabled enhanced type checking it will result in sending passwords (if revealed) to their servers in plain text. More details about this vulnerability can be found <a href="https://www.otto-js.com/news/article/spell-jacking-enhanced-spellcheck-features-send-pii-even-passwords">here</a>. </p>
<p>This is very concerning and exposes the risk of legal actions as it might result in sending the PII of your customers to services with which you do not have any agreement about PII data processing. Due to this any app owner should act swiftly and implement necessary changes.</p>
<h2 id="heading-vulnerability-details">Vulnerability details</h2>
<p>This vulnerability is a coincidence of 3 features that improve user experience. Password reveal is a very common feature this day - it allows customers to double check if the inputted password is correct. Enhanced spell checking enables you to use the same spellchecking as popular services (like Google Search) by sending inputted values to external (online) services. Spellchecking attribute - enabled by default in some browsers - allows users to input proper values into forms, which improves the experience (especially on mobile devices where the input interface is not as efficient as traditional PC).</p>
<p>Before you will say that's not an issue at all. Please consider that the security of spellchecking services by default is much lower than PII processing services. We do know that every service can be hacked with enough effort. The ability to obtain a username + password is very tempting for bad actors all over the world.</p>
<h2 id="heading-how-to-mitigate-this">How to mitigate this?</h2>
<p>By default, you should start adding <code>spellcheck="false"</code> attribute to all sensitive inputs (like username, password, and other sensitive PII). Ideally, you should reconsider adding it to all inputs that hold customer data (even inputs like the first name, and last name). You can also add <code>spellcheck="false"</code> to the <code>&lt;form&gt;</code> tag which should disable spellchecking for the whole form.</p>
<p>Ideally, you should implement an automatic rule that will be checking all your fields &amp; forms automatically with every code change.</p>
<h2 id="heading-eslint-rules">Eslint rules</h2>
<p>For the React-based web application, I've created a set of eslint rules (as a plugin) that can go through the code and scan for this vulnerability, and propose a fix. Plugin is called <a href="https://www.npmjs.com/package/eslint-plugin-jsx-secure-form">eslint-plugins-jsx-secure-form</a>. It can be simply added as a dev dependency by running
<code>npm install --development eslint eslint-plugin-jsx-secure-form</code> and adding <code>"extends": ["plugin:jsx-secure-form/recommended"],</code> to your eslint configuration file.</p>
]]></content:encoded></item></channel></rss>