<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: tirixa</title>
    <description>The latest articles on Forem by tirixa (@tirixa).</description>
    <link>https://forem.com/tirixa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F13050%2F3de44f5b-0f46-4572-9203-f695fdc89dc4.png</url>
      <title>Forem: tirixa</title>
      <link>https://forem.com/tirixa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/tirixa"/>
    <language>en</language>
    <item>
      <title>The Magic Behind Ruby: An Unofficial Guide to Its Power and Simplicity</title>
      <dc:creator>Evgeny N</dc:creator>
      <pubDate>Sun, 19 Apr 2026 00:23:43 +0000</pubDate>
      <link>https://forem.com/tirixa/the-magic-behind-ruby-an-unofficial-guide-to-its-power-and-simplicity-52n0</link>
      <guid>https://forem.com/tirixa/the-magic-behind-ruby-an-unofficial-guide-to-its-power-and-simplicity-52n0</guid>
      <description>&lt;p&gt;Hey fellow developers,&lt;/p&gt;

&lt;p&gt;If you've been in the software development world for even a short time, you've probably encountered Ruby. This elegant language has been around for quite a while, but it's still one of the most beloved by developers for its simplicity and productivity. Today, I want to share my personal experiences with Ruby and why I still think it's one of the most powerful languages out there, despite the rise of newer contenders.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Ruby Still Holds Its Ground
&lt;/h2&gt;

&lt;p&gt;First off, Ruby's philosophy is simple: "Optimized for developer happiness." It's all about making your coding experience as pleasant and intuitive as possible. And trust me, once you get into Ruby, you’ll see exactly what I mean. The syntax is clean, easy to read, and intuitive. In short, it feels like writing in plain English—well, programming English at least.&lt;/p&gt;

&lt;p&gt;But let’s get to the meat of it: how Ruby powers real-world apps and what makes it so great. Over the years, I've used Ruby for various projects, ranging from quick prototypes to massive-scale applications. And I can tell you, Ruby’s elegance always wins me over. Whether you're building APIs or web apps, Ruby never feels too heavy-handed or complicated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deep Dive into Ruby’s Power
&lt;/h2&gt;

&lt;p&gt;One thing I love about Ruby is its object-oriented nature. Everything in Ruby is an object, even simple data types like numbers and strings. This means you can extend these built-in classes, tweak them, or even write your own. It gives you a lot of freedom.&lt;/p&gt;

&lt;p&gt;Let's take an example. Here's a Ruby class that mimics a basic data store system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DataStore&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
    &lt;span class="vi"&gt;@data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show_all&lt;/span&gt;
    &lt;span class="vi"&gt;@data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, what makes this Ruby code so elegant is its simplicity. You define your &lt;code&gt;DataStore&lt;/code&gt;class, initialize the data, and then you can add and display items. But notice how you never had to deal with some of the boilerplate code you often find in other object-oriented languages. Ruby keeps things neat and concise.&lt;/p&gt;

&lt;p&gt;One thing that stands out is Ruby’s block functionality. Blocks in Ruby are like functions passed to methods, but they're even more versatile. This leads to cleaner, more readable code.&lt;/p&gt;

&lt;p&gt;Here’s an example of Ruby’s block with iterators:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_items&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="s2"&gt;"apple"&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="s2"&gt;"banana"&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="s2"&gt;"orange"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;process_items&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Processing &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The beauty of Ruby blocks is their ability to make the code more compact and expressive. No need to mess around with extra method declarations, parameters, or return statements. You just get things done.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Ruby on Rails Effect
&lt;/h2&gt;

&lt;p&gt;Now, I can’t talk about Ruby without mentioning its most famous framework: Ruby on Rails. It's like the wind beneath Ruby’s wings, powering some of the most successful startups and apps out there. Rails is opinionated and follows the "convention over configuration" principle, which means you don’t spend time configuring stuff that Rails assumes you want. It just works, and you can focus on writing the logic that matters.&lt;/p&gt;

&lt;p&gt;When I first jumped into Rails, I was absolutely blown away by its developer-friendly features. The way it handles routing, migrations, and database relations is so straightforward.&lt;/p&gt;

&lt;p&gt;Let’s consider a quick example of how easy it is to set up an ActiveRecord model (Rails' ORM):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Product&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
  &lt;span class="n"&gt;belongs_to&lt;/span&gt; &lt;span class="ss"&gt;:category&lt;/span&gt;
  &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:reviews&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a few lines of code, you’ve defined relationships between models. Imagine writing that in other frameworks—there’s usually so much boilerplate! But Rails abstracts the complexity and makes things easy to manage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ruby's Metaprogramming Magic
&lt;/h2&gt;

&lt;p&gt;Ruby’s metaprogramming capabilities are where things get really fun. Metaprogramming allows you to modify Ruby classes and methods dynamically at runtime. This can be a bit tricky to grasp at first, but it’s incredibly powerful.&lt;/p&gt;

&lt;p&gt;Here’s a basic example of how Ruby’s metaprogramming works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; called with &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:say_hello&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="nb"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;say_hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Ruby"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code defines a class &lt;code&gt;Person&lt;/code&gt; with a method &lt;code&gt;create_method&lt;/code&gt; that generates new methods dynamically. This kind of flexibility is exactly what makes Ruby a joy to work with, but it’s also a double-edged sword—use metaprogramming sparingly and wisely!&lt;/p&gt;

&lt;h2&gt;
  
  
  Some Ruby Gotchas
&lt;/h2&gt;

&lt;p&gt;As much as I love Ruby, it’s not all rainbows and butterflies. One thing you need to watch out for is its garbage collection. Ruby does automatic memory management, but that doesn’t mean you can’t encounter performance bottlenecks. Sometimes, especially in memory-heavy applications, Ruby’s garbage collection process might slow things down.&lt;/p&gt;

&lt;p&gt;Another issue you might run into is its speed compared to languages like C++ or Go. Ruby is an interpreted language, which means it doesn’t have the raw performance of compiled languages. But for most web apps and services, Ruby’s performance is more than sufficient. If performance becomes an issue, you can always optimize your Ruby code or implement critical sections in C or JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: The Joy of Ruby
&lt;/h2&gt;

&lt;p&gt;At the end of the day, Ruby is all about making the developer's life easier. Its expressive syntax, powerful metaprogramming features, and the developer-friendly Rails framework make it a joy to work with. Sure, there are other languages out there, but Ruby’s focus on productivity and simplicity keeps it relevant.&lt;/p&gt;

&lt;p&gt;So if you haven’t given Ruby a serious look yet, what are you waiting for? It’s a language that rewards you for taking the time to learn it. Dive in, and you might just fall in love with it like I did.&lt;/p&gt;

&lt;p&gt;Happy coding, and enjoy the Ruby magic! ✨&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>programming</category>
      <category>simplicity</category>
      <category>ai</category>
    </item>
    <item>
      <title>Building Powerful Backends: Python Frameworks that Shine</title>
      <dc:creator>Alina K</dc:creator>
      <pubDate>Sat, 18 Apr 2026 23:57:27 +0000</pubDate>
      <link>https://forem.com/tirixa/building-powerful-backends-python-frameworks-that-shine-4on</link>
      <guid>https://forem.com/tirixa/building-powerful-backends-python-frameworks-that-shine-4on</guid>
      <description>&lt;p&gt;When it comes to building backend applications, Python is one of the top languages many developers turn to. With its versatility, ease of use, and robust ecosystem, it's no surprise that Python powers everything from web apps to complex data pipelines. Among the variety of Python frameworks, Django, Flask, and FastAPI have carved out their own niches. In this article, I'll dive into these three popular backend frameworks, explore what makes them special, and discuss when to choose each.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Django: The Heavyweight Champion
&lt;/h2&gt;

&lt;p&gt;When most developers think of Python for backend development, Django is often the first framework that comes to mind. It's a full-stack framework that provides a lot of "batteries included" functionality, which makes it perfect for large, feature-rich applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Makes Django Stand Out:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Built-In Admin Panel: One of the coolest features of Django is its auto-generated admin panel. This comes in handy when building an application quickly and needs a simple interface to manage your models.&lt;/li&gt;
&lt;li&gt;MTV Pattern: Django follows the Model-Template-View architecture, which is a variant of MVC. This ensures a clean separation of concerns and a highly maintainable codebase.&lt;/li&gt;
&lt;li&gt;Security Features: Django has built-in protection against common security threats like CSRF, SQL injection, and XSS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to Use Django:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're building a complex web application with lots of features.&lt;/li&gt;
&lt;li&gt;You want to follow the DRY (Don’t Repeat Yourself) principle.&lt;/li&gt;
&lt;li&gt;You need a framework that provides a lot of tools out of the box (like admin, authentication, and more).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Flask: The Minimalist's Dream
&lt;/h2&gt;

&lt;p&gt;Flask is the exact opposite of Django in some ways. It's a micro-framework, meaning it gives you the basics to get started but doesn't try to do everything for you. This lightweight approach gives you a lot of freedom to choose how to structure your application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Makes Flask Special:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simplicity and Flexibility: Flask is often praised for its minimalism. It doesn't impose anything on you — no ORM, no admin panel, no restrictions on how to organize your project.&lt;/li&gt;
&lt;li&gt;Great for Small Apps: Flask is perfect for small applications or APIs. It's super fast to get started with, and you don't need to wade through tons of configuration to get your app up and running.&lt;/li&gt;
&lt;li&gt;Extensibility: Flask allows you to add only the components you need, making it a good fit for projects where you want to keep the footprint minimal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to Use Flask:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're building a small to medium-sized application or API.&lt;/li&gt;
&lt;li&gt;You want complete control over the components you use.&lt;/li&gt;
&lt;li&gt;You're looking for something that’s easy to pick up and build with quickly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. FastAPI: Modern and Super-Fast
&lt;/h2&gt;

&lt;p&gt;FastAPI is a newer player in the Python backend world but has quickly gained traction for its speed and efficiency. If you need a framework that’s high-performing and built with modern development practices in mind, FastAPI should be on your radar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Makes FastAPI Stand Out:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: FastAPI is one of the fastest Python frameworks out there. It’s built on top of Starlette and Pydantic, and because it’s asynchronous, it can handle many requests concurrently, making it ideal for building fast APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic Docs&lt;/strong&gt;: One of FastAPI’s standout features is that it automatically generates OpenAPI documentation for your API, which is a huge time-saver. This makes testing and using your API a breeze.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asynchronous Support&lt;/strong&gt;: FastAPI is designed for asynchronous programming, meaning you can build highly performant and scalable APIs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When to Use FastAPI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're building an API that needs to be ultra-fast and scalable.&lt;/li&gt;
&lt;li&gt;You prefer asynchronous development and want to work with modern Python features like type hints.&lt;/li&gt;
&lt;li&gt;You need automatic documentation generation for your API.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Choosing the Right Framework for Your Project
&lt;/h2&gt;

&lt;p&gt;Choosing between Django, Flask, and FastAPI isn’t always easy, but it all depends on your project’s needs. Here's a quick breakdown:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go with Django if you need a full-stack solution with tons of built-in features and you’re building something with a lot of business logic (e.g., an e-commerce platform or a content management system).&lt;/li&gt;
&lt;li&gt;Choose Flask if you want flexibility and simplicity for small to medium-sized applications. Flask is great for building APIs or lightweight projects where you control every aspect of the app.&lt;/li&gt;
&lt;li&gt;Pick FastAPI if you need speed and scalability, especially if you're building an API. FastAPI is great for high-performance systems, real-time apps, or anything requiring async programming.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;All three of these frameworks are amazing in their own right and are well-suited for different types of projects. Whether you're a fan of Django's batteries-included philosophy, Flask’s minimalism, or FastAPI’s lightning-fast performance, there’s no wrong choice. It all boils down to what you need for your project. Happy coding!&lt;/p&gt;

</description>
      <category>backend</category>
      <category>python</category>
      <category>fastapi</category>
      <category>flask</category>
    </item>
    <item>
      <title>Introduction to Blockchain Development: A Friendly Dive Into Web3 with Python and Rust</title>
      <dc:creator>Joao F</dc:creator>
      <pubDate>Sat, 18 Apr 2026 16:33:56 +0000</pubDate>
      <link>https://forem.com/tirixa/introduction-to-blockchain-development-a-friendly-dive-into-web3-with-python-and-rust-5234</link>
      <guid>https://forem.com/tirixa/introduction-to-blockchain-development-a-friendly-dive-into-web3-with-python-and-rust-5234</guid>
      <description>&lt;p&gt;Hey there, blockchain enthusiasts! If you're just stepping into the world of blockchain development, you're in for an exciting journey. Blockchain isn’t just about cryptocurrency (though that's where it started). The potential stretches far beyond, transforming industries from finance to gaming, and beyond into what we now call Web3.&lt;/p&gt;

&lt;p&gt;In this article, I'll walk you through how you can use Python and Rust to build decentralized applications (DApps) and smart contracts on blockchain. It's all about making the complex tech approachable while keeping things as fun as possible. So, buckle up – let’s break it down!&lt;/p&gt;

&lt;h2&gt;
  
  
  1. What is Web3 and How Does Blockchain Fit In?
&lt;/h2&gt;

&lt;p&gt;Before we jump into the coding side, let's quickly touch on what Web3 really means. You’ve probably heard the term thrown around a lot. In simple terms, Web3 is the next iteration of the internet. It's decentralized, permissionless, and transparent. And here’s the best part – you get to be a part of it.&lt;/p&gt;

&lt;p&gt;At the heart of Web3 is blockchain, which ensures that data isn't stored in centralized servers. Instead, it’s distributed across a network of nodes, meaning that control isn’t held by a single entity. This is especially crucial in areas like finance (hello, DeFi), art (hello, NFTs), and social media (goodbye, centralized control!).&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Using Python for Blockchain Development
&lt;/h2&gt;

&lt;p&gt;Python isn’t the first language that comes to mind when you think "blockchain," but trust me, it’s incredibly useful. If you're already familiar with Python, you’re ahead of the game. The Python ecosystem is rich with libraries and tools that make it easier to interact with blockchains, build DApps, or even create your own blockchain.&lt;/p&gt;

&lt;p&gt;Tools You’ll Love:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web3.py: A Python library that makes interacting with Ethereum (and other EVM chains) a breeze. It’s perfect for building decentralized apps, managing wallets, and interacting with smart contracts.&lt;/li&gt;
&lt;li&gt;Flask/Django: These Python web frameworks can help you quickly build the front-end for your DApp, integrating it seamlessly with your blockchain backend.&lt;/li&gt;
&lt;li&gt;Brownie: A Python-based development framework for Ethereum smart contracts. It helps you write, test, and deploy contracts easily.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A Sample Python Smart Contract Deployment:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;web3&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Web3&lt;/span&gt;

&lt;span class="c1"&gt;# Connect to Ethereum node
&lt;/span&gt;&lt;span class="n"&gt;w3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Web3&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Web3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HTTPProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://mainnet.infura.io/v3/YOUR_PROJECT_ID&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# Check if connection is successful
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;w3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isConnected&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="c1"&gt;# Interact with smart contracts (e.g., simple token contract)
&lt;/span&gt;&lt;span class="n"&gt;contract_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0xYourContractAddressHere&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;contract_abi&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...]&lt;/span&gt;  &lt;span class="c1"&gt;# ABI JSON
&lt;/span&gt;&lt;span class="n"&gt;contract&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;w3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;contract_address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;abi&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;contract_abi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Call a function from the contract
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;functions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;balanceOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;0xYourAddressHere&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Balance: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See? Super easy to get started, and Python’s simplicity is great for beginners.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Rust: The Powerhouse for Smart Contract Development
&lt;/h2&gt;

&lt;p&gt;While Python is great for blockchain applications, Rust has become the go-to language for building high-performance smart contracts, particularly in blockchain platforms like Solana and Polkadot. Why? Well, Rust offers memory safety without sacrificing performance, which is crucial when dealing with blockchain’s low-level operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Rust for Smart Contracts?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Performance: Blockchain applications often need to execute thousands of transactions per second. Rust can handle that with ease, especially compared to other languages.&lt;/li&gt;
&lt;li&gt;Safety: Rust’s ownership system ensures that smart contracts are memory-safe, eliminating many common errors in blockchain development.&lt;/li&gt;
&lt;li&gt;Concurrency: If you're building a high-performance, multi-threaded application, Rust's concurrency model is hard to beat.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example of a Rust-based Smart Contract on Solana:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;solana_program&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;program_error&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ProgramError&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;solana_program&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nd"&gt;#[program]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;mod&lt;/span&gt; &lt;span class="n"&gt;my_token&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;process_transaction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TransactionContext&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;ProgramError&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nd"&gt;msg!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processing transaction of {} tokens!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// Further implementation here...&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rust gives you control over low-level blockchain interactions while ensuring performance and safety—perfect for building secure, high-speed decentralized applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Why Python + Rust = A Winning Combo for Blockchain Development
&lt;/h2&gt;

&lt;p&gt;Now, you might be thinking: "Why not just stick to one language?" Here’s the thing: each language has its strengths. Python is excellent for rapid development and is great for the application layer, while Rust is unbeatable for smart contract performance and low-level blockchain interactions.&lt;/p&gt;

&lt;p&gt;By combining the two, you get the best of both worlds. You can leverage Python’s ease of use for developing the frontend of your blockchain application, and Rust’s power to write secure, fast, and reliable smart contracts.&lt;/p&gt;

&lt;p&gt;Imagine building the user-friendly interface for a DeFi app in Python while using Rust to handle the smart contract logic. The result? A high-performance, scalable, and user-friendly application.&lt;/p&gt;

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

&lt;p&gt;And there you have it! Blockchain development might sound intimidating at first, but with the right tools and approach, you’ll be building DApps and writing smart contracts in no time. Whether you’re using Python for quick iteration and ease of use, or Rust for performance and security, both languages can help you thrive in the world of Web3 development.&lt;/p&gt;

&lt;p&gt;So, if you’re just starting out in blockchain, I encourage you to explore both Python and Rust. Build something fun, experiment, and most importantly – enjoy the journey. Who knows? Your next big blockchain app could be just around the corner! 🚀&lt;/p&gt;

</description>
      <category>web3</category>
      <category>python</category>
      <category>rust</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Building Scalable Blockchain Solutions with Go: A Developer's Journey</title>
      <dc:creator>Yehor A</dc:creator>
      <pubDate>Sat, 18 Apr 2026 15:20:48 +0000</pubDate>
      <link>https://forem.com/tirixa/building-scalable-blockchain-solutions-with-go-a-developers-journey-360m</link>
      <guid>https://forem.com/tirixa/building-scalable-blockchain-solutions-with-go-a-developers-journey-360m</guid>
      <description>&lt;p&gt;As a senior Go developer with nine years of industry experience, I've had the privilege of working on a wide range of complex projects, many of which revolved around creating scalable, high-performance systems. But the path to where I am now wasn’t always clear-cut. It’s been a journey filled with constant learning, collaboration, and, most importantly, a passion for solving real-world problems with technology.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Backend to Blockchain
&lt;/h2&gt;

&lt;p&gt;When I first started in software development, the focus was predominantly on backend systems. I spent years honing my skills in creating high-performance applications using Golang. This included building microservices, APIs, and databases—each of which required scalability, reliability, and speed. What I didn’t realize at the time was that these foundational skills would perfectly set the stage for my future work in blockchain technology.&lt;/p&gt;

&lt;p&gt;The transition into the world of blockchain was not immediate. Initially, I was focused on traditional backend systems—designing reliable microservices, integrating cloud-native solutions with Docker, Kubernetes, and AWS, and architecting systems capable of handling millions of users without breaking a sweat. But as the blockchain ecosystem began to grow, I couldn’t ignore its potential, and my curiosity was piqued.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Blockchain Revolution: Why Go?
&lt;/h2&gt;

&lt;p&gt;One of the biggest questions I faced was: "How does blockchain fit into my existing skill set?" At the time, Go wasn’t the first language most developers thought of when it came to building decentralized applications or smart contracts. Languages like Solidity and Rust had already made a name for themselves in the space. But after some deep research and experimentation, I realized that Go’s performance and concurrency model were perfect for building the high-load systems that blockchain demands.&lt;/p&gt;

&lt;p&gt;Blockchain requires high scalability and efficiency, especially in areas like transaction verification, consensus algorithms, and distributed ledgers. Go's simplicity, speed, and concurrency made it an ideal choice for developing these systems. More importantly, Go allowed me to create applications that could seamlessly integrate with decentralized networks while ensuring high throughput.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building Decentralized Solutions
&lt;/h2&gt;

&lt;p&gt;With Go as my weapon of choice, I dove headfirst into building decentralized solutions. My first project involved working with Ethereum and smart contracts. Developing smart contracts in Solidity was a learning curve, but applying Go to the backend system that interacted with the Ethereum blockchain was where the magic happened. I was able to leverage Go’s efficient handling of concurrent tasks to create a seamless connection between the blockchain and the systems it powered.&lt;/p&gt;

&lt;p&gt;One of the more interesting challenges I faced was scaling a decentralized application for industrial IoT devices. With blockchain’s immutable ledger ensuring transparency and security, we were able to deliver a cloud processing solution that increased system performance by an astounding 20,000%. This was a clear demonstration of how blockchain, combined with Go’s capabilities, can radically transform industries by ensuring data integrity and high availability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaling for the Future: Go and Blockchain
&lt;/h2&gt;

&lt;p&gt;While I’ve worked on many complex systems over the years, nothing quite compares to the excitement of working on blockchain technology. The opportunities for innovation in decentralized finance (DeFi), supply chain, identity management, and beyond are immense. In fact, one of my most fulfilling projects was developing a decentralized mobile advertising network capable of processing 1300 requests per second. The backend, powered by Go, allowed us to handle massive throughput without compromising on speed or reliability.&lt;/p&gt;

&lt;p&gt;Blockchain, as a technology, is still evolving, and Go is rapidly becoming a preferred language for building scalable blockchain applications. What I find most compelling is the ability to integrate traditional cloud-native tools—like Kubernetes and AWS—with blockchain, bridging the gap between legacy systems and the future of decentralized solutions. The combination of Go’s speed and scalability with blockchain’s decentralized nature is what makes these projects truly exciting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned and Moving Forward
&lt;/h2&gt;

&lt;p&gt;If there’s one lesson I’ve learned from my journey, it’s that success in technology comes down to two things: continuous learning and building systems that work. I didn’t just want to be a developer; I wanted to be someone who could solve complex problems by creating scalable solutions that would withstand the test of time.&lt;/p&gt;

&lt;p&gt;In my work, I’ve always emphasized the importance of collaboration. Whether it's working with cross-functional remote teams or communicating with clients to understand their pain points, collaboration has been key to delivering solutions that meet real-world needs. My work with blockchain is no different. As blockchain continues to mature, it’s clear that the future belongs to those who can create scalable, reliable systems that integrate seamlessly with the decentralized web.&lt;/p&gt;

&lt;p&gt;If you’re looking to integrate blockchain into your system, or if you need help scaling a high-load system that’s both secure and decentralized, I’d love to work with you. Together, we can build something amazing.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>go</category>
      <category>smartcontract</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Exploring the Future of Trading: Staking, Stocks, and Loans</title>
      <dc:creator>Niels</dc:creator>
      <pubDate>Sat, 18 Apr 2026 12:00:03 +0000</pubDate>
      <link>https://forem.com/tirixa/exploring-the-future-of-trading-staking-stocks-and-loans-3586</link>
      <guid>https://forem.com/tirixa/exploring-the-future-of-trading-staking-stocks-and-loans-3586</guid>
      <description>&lt;p&gt;The world of trading has always been a dynamic and fast-evolving domain. Whether you’re an investor looking to diversify your portfolio, a trader aiming to profit from market fluctuations, or someone seeking innovative ways to generate passive income, the landscape offers myriad opportunities. From traditional stock trading to emerging concepts like staking and decentralized finance (DeFi), the avenues to explore are broad and diverse. This article delves into key components of modern trading and offers insights into how staking, stocks, and loans intersect in today’s market.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Staking: A Passive Income Opportunity
&lt;/h2&gt;

&lt;p&gt;Staking has emerged as a powerful tool in the cryptocurrency ecosystem, allowing holders of digital assets to lock their tokens in a blockchain network to support its operations. In return, participants earn rewards, typically in the form of additional tokens. But why is this concept becoming more than just a niche activity?&lt;/p&gt;

&lt;p&gt;At its core, staking aligns the interests of token holders with the overall health and success of a blockchain network. When users stake their tokens, they help secure the network and validate transactions, enhancing the decentralization and security of the system. For those seeking passive income, staking offers an attractive alternative to traditional investment vehicles, where returns are generally tied to high-risk market movements.&lt;/p&gt;

&lt;p&gt;However, it’s important to consider that staking isn’t without risks. Depending on the blockchain, staking can require long-term commitment, and there is always the possibility of slashing—losing part of your staked tokens if you fail to comply with network rules.&lt;/p&gt;

&lt;p&gt;Despite this, staking provides an opportunity for diversification and exposure to a rapidly growing segment of the market. It is not just about making money off digital assets, but about participating in the long-term success of a decentralized ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stock Trading: The Traditional Yet Evolving Game
&lt;/h2&gt;

&lt;p&gt;While cryptocurrencies and DeFi platforms continue to capture attention, traditional stock trading remains a cornerstone of global finance. Stocks represent ownership in a company and have long been considered a primary way for individuals and institutions to invest in businesses and industries. From tech giants to emerging startups, the stock market offers a broad spectrum of opportunities to trade.&lt;/p&gt;

&lt;p&gt;However, as with any investment, stock trading involves risk. Prices fluctuate due to various factors—market sentiment, economic conditions, geopolitical events, and corporate performance. The rise of algorithmic trading and the democratization of trading platforms like Robinhood and Webull has further changed the landscape, making trading more accessible to retail investors. Today, anyone with a smartphone can buy and sell stocks, engage in fractional ownership, and utilize tools like options and margin trading.&lt;/p&gt;

&lt;p&gt;Moreover, advancements like AI-driven stock analysis and sentiment prediction tools are reshaping how traders make decisions. Algorithms now crunch vast amounts of data, providing insights that were once reserved for institutional investors. These tools can provide an edge, but they also come with the challenge of understanding the underlying algorithms and knowing when to trust the data they produce.&lt;/p&gt;

&lt;p&gt;Incorporating these AI-driven solutions into stock trading, however, requires both a keen understanding of market trends and technological proficiency. Balancing between data-driven insights and traditional market analysis is the key to navigating the complexities of stock trading.&lt;/p&gt;

&lt;h2&gt;
  
  
  Loans and Trading: A Growing Nexus
&lt;/h2&gt;

&lt;p&gt;While many associate loans with the realm of personal finance, they also play an increasingly vital role in the world of trading and investing. Margin trading, where investors borrow funds to increase their market exposure, is one example of how loans intersect with trading. This strategy amplifies potential returns but also comes with heightened risks—especially in volatile markets.&lt;/p&gt;

&lt;p&gt;In cryptocurrency markets, lending platforms have sprung up, allowing users to borrow or lend digital assets. For instance, in DeFi, platforms like Aave and Compound allow users to deposit cryptocurrencies to earn interest or borrow against their assets. In the world of stocks, margin loans are still widely used, enabling traders to borrow money from brokers to leverage their positions.&lt;/p&gt;

&lt;p&gt;However, while margin trading can enhance profits, it can also magnify losses. It’s essential to understand the implications of borrowed funds in trading and the need for strict risk management strategies. The key to using loans successfully in trading is ensuring that the potential rewards justify the risks taken and that you are well-prepared for any market downturns.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future of Trading: Integration and Innovation
&lt;/h2&gt;

&lt;p&gt;As the world of finance evolves, so does the way we trade. From decentralized exchanges (DEXs) to automated trading systems, the future of trading is defined by integration and innovation. Staking, stocks, loans, and other trading mechanisms are becoming interconnected, offering a comprehensive ecosystem where digital and traditional assets coexist.&lt;/p&gt;

&lt;p&gt;The rise of blockchain technology and decentralized finance is pushing the boundaries of what is possible. Staking rewards and liquidity mining are becoming more intertwined with traditional markets, and it’s only a matter of time before we see deeper integration between these ecosystems. Trading platforms are adapting to this shift by offering more tools and assets to a broader audience, enabling both beginner and professional traders to participate in a unified marketplace.&lt;/p&gt;

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

&lt;p&gt;Trading is no longer confined to the realms of stock exchanges or crypto markets. With new innovations such as staking, margin loans, and DeFi protocols, the landscape is rapidly evolving. While there are significant opportunities to explore, understanding the risks and diversifying your strategies remains essential. Whether you’re staking digital assets for passive income, trading stocks with advanced algorithms, or using loans to leverage positions, it’s crucial to remain adaptable and informed.&lt;/p&gt;

&lt;p&gt;The future of trading isn’t about one asset class or strategy—it's about creating an ecosystem that thrives on innovation, collaboration, and a deeper understanding of the global financial markets. The next generation of traders will need to be as fluent in decentralized finance as they are in traditional investment techniques, and the best strategies will combine both to navigate this new era of financial opportunity.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>productivity</category>
      <category>architecture</category>
    </item>
    <item>
      <title>When Debugging Became Belonging: What Nearly 15 Years of Helping Developers Taught Me</title>
      <dc:creator>Niels</dc:creator>
      <pubDate>Mon, 30 Mar 2026 12:54:16 +0000</pubDate>
      <link>https://forem.com/tirixa/when-debugging-became-belonging-what-nearly-15-years-of-helping-developers-taught-me-3amg</link>
      <guid>https://forem.com/tirixa/when-debugging-became-belonging-what-nearly-15-years-of-helping-developers-taught-me-3amg</guid>
      <description>&lt;p&gt;The first time code made me question my place in tech, it was not elegant.&lt;/p&gt;

&lt;p&gt;It was not cinematic either, unless your favorite genre is “junior developer stares at legacy JavaScript while silently bargaining with the universe.” Mine happened on a gray Monday morning, the kind of morning where even coffee feels underqualified. I had just been given my first real bug on my first real project at a company paying me real money to write code. That should have felt empowering. Instead, it felt like being handed a fork and asked to repair a jet engine.&lt;/p&gt;

&lt;p&gt;The instruction was almost offensive in its simplicity: “Just fix this bug.”&lt;/p&gt;

&lt;p&gt;Anyone who has worked with old code knows that “just” is one of the most dangerous words in software development. I opened the file and found the usual archaeological layers of logic, half-decisions, mysterious comments, and code that looked like three different developers had fought each other and the code had won. I tried to run the app. Errors. I changed something. More errors. I changed something else. New errors, different font, same emotional damage.&lt;/p&gt;

&lt;p&gt;For a while, I did what many early-career developers do but rarely admit out loud: I mistook confusion for incompetence.&lt;/p&gt;

&lt;p&gt;I was not only debugging the application. I was debugging my confidence. I wondered whether I belonged in tech, whether the recruiter had emailed the wrong person, whether my future career path might somehow involve leaving software altogether and becoming a professional yodeler in Switzerland. It felt dramatic at the time. In hindsight, it was dramatic. But it was also real.&lt;/p&gt;

&lt;p&gt;And then I did the thing that scared me most.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrr5ftcnphczuu233mcs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrr5ftcnphczuu233mcs.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I asked for help.&lt;/p&gt;

&lt;p&gt;I still remember how big that tiny sentence felt: “I’m stuck. I don’t know what to do.”&lt;/p&gt;

&lt;p&gt;What changed me was not just that someone answered. It was how she answered. A senior engineer walked me through the logic without making me feel small. She did not treat my confusion like a personal failure. She treated it like part of the craft. She showed me where the code bent, where it broke, and where I could safely touch it without summoning six new production incidents. Less than an hour later, I fixed the bug.&lt;/p&gt;

&lt;p&gt;That should have been the victory. But it was not.&lt;/p&gt;

&lt;p&gt;The real victory was learning that asking for help was not proof that I was weak. It was proof that I was still in the fight.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmyqbd5uw6d9og8rct0kx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmyqbd5uw6d9og8rct0kx.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That lesson stayed with me far longer than the bug did. Since then, I have met deadlines that felt like punishment, APIs that behaved like they had a private grudge against me, and merge conflicts that probably qualify as spiritual warfare. But I have also learned that growth in this industry rarely arrives looking polished. Usually it arrives wearing panic, carrying a stack trace, and asking whether you have tried turning your assumptions off and on again.&lt;/p&gt;

&lt;p&gt;That is one reason the idea of WeCoded matters to me.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs68qlkhqbzfxdc3bvtmj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs68qlkhqbzfxdc3bvtmj.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Too many developers, especially those from underrepresented and marginalized genders, spend part of their careers being made to feel that uncertainty is something shameful. That not knowing is a flaw. That asking questions is a weakness. But the healthiest technical spaces I have ever seen were not the ones full of people performing brilliance. They were the ones full of people practicing generosity.&lt;/p&gt;

&lt;p&gt;The engineers who changed my life were not always the loudest people in the room. They were the ones who made room. They explained without humiliating. They corrected without performing superiority. They understood that inclusion is not a slogan you put on a company page. It is a daily engineering practice. It is visible in code reviews, in mentoring, in who gets heard, in who gets interrupted, in who feels safe saying, “I don’t understand this yet.”&lt;/p&gt;

&lt;p&gt;That word matters: yet.&lt;/p&gt;

&lt;p&gt;Because “yet” has carried a lot of developers farther than talent alone ever could.&lt;/p&gt;

&lt;p&gt;For me, that journey did not stop at surviving hard moments in code. Over time, it turned into a habit of showing up for other developers too. For nearly fifteen years, I have been active on Stack Overflow under the name Niels, where I have built a record of more than 50,000 reputation, 680 answers, and 40 questions, with strong activity around JavaScript, jQuery, MySQL, HTML, and PHP. &lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://stackoverflow.com/users/1041948/niels" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstackoverflow.com%2FContent%2FSites%2Fstackoverflow%2FImg%2Fapple-touch-icon%402.png%3Fv%3D0f0cab681579" height="360" class="m-0" width="360"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://stackoverflow.com/users/1041948/niels" rel="noopener noreferrer" class="c-link"&gt;
            User Niels - Stack Overflow
          &lt;/a&gt;
        &lt;/h2&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fstackoverflow.com%2FContent%2FSites%2Fstackoverflow%2FImg%2Ffavicon.ico%3Fv%3D562fb39d93c8" width="48" height="48"&gt;
          stackoverflow.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;My profile still describes the same practical mix of technologies and the same instinct to help others that shaped me early on.&lt;/p&gt;

&lt;p&gt;And honestly, that long Stack Overflow chapter taught me something important about community: most of software is not built by isolated genius. It is built by people answering each other’s questions on ordinary weekdays.&lt;/p&gt;

&lt;p&gt;One person asks why their URL parameters are breaking. Another asks how to reset an auto-increment value in MySQL. Someone else is fighting jQuery, as humanity has done for generations. The problems are rarely glamorous, but the act itself is powerful. Every answer is a small vote for access. Every explanation says, “You do not have to stay stuck here alone.”&lt;/p&gt;

&lt;p&gt;That same spirit is exactly why I wanted my first real Dev.to post to be more than just another article sitting in a browser tab.&lt;/p&gt;

&lt;p&gt;So I built something around the reading experience itself.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/yDOffm739Ag"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The project I prepared is Always with Dev.to — Desktop Client, a cross-platform Electron desktop application designed to wrap Dev.to into a more native, focused experience. It uses vanilla JavaScript, HTML, and CSS inside Electron, with an embedded Express backend that proxies the Dev.to public API, handles authentication, and manages caching, all packaged into a single portable executable with no installation required.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhb3f6gt6xzdhyep13e44.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhb3f6gt6xzdhyep13e44.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What I love about that project is that it reflects how I now think about software: not just “Does it run?” but “Does it make the experience kinder, simpler, and more useful?”&lt;/p&gt;

&lt;p&gt;The interesting part was not only the interface. It was the engineering behind the convenience. I embedded the backend directly into the Electron main process rather than forcing a separate backend service and extra orchestration. I packaged the app as a single portable .exe while carrying the backend resources with it. I added in-memory LRU caching with TTL and pattern invalidation to avoid hammering the Dev.to API. I used retry logic with exponential backoff for transient failures, added lazy Supabase initialization for authentication, and documented lessons from painful but useful issues like response-shape mismatches, temporal dead zone crashes, and a later layered-architecture refactor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Embedding a backend server inside Electron&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The challenge: Electron apps typically need a separate backend process, requiring IPC, process spawning, and port management. Instead, the Express server runs directly inside the Electron main process.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// frontend/main.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;startEmbeddedBackend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;3000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isDev&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPackaged&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;envPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isDev&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;..&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;backend&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.env&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resourcesPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;backend&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.env&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;envPath&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serverPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isDev&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;..&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;backend&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;server.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resourcesPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;backend&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;server.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;serverPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Backend server started on port 3000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Backend failed to start:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;whenReady&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;startEmbeddedBackend&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// server starts before window opens&lt;/span&gt;
  &lt;span class="nf"&gt;createWindow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;require(serverPath)&lt;/code&gt; loads the Express app into the same Node.js process Electron is already running. No child process, no IPC, no port negotiation. The &lt;code&gt;.env&lt;/code&gt; path switches between dev (source tree) and production (&lt;code&gt;process.resourcesPath&lt;/code&gt;) automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building a single portable .exe&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The challenge: packaging an Electron app with an embedded Express backend — including all backend &lt;code&gt;node_modules&lt;/code&gt; — into one file that runs without installation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;frontend/package.json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(build&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;config)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"win"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"portable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"arch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"x64"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"icon.ico"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"signAndEditExecutable"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"extraResources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"from"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"../backend"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"to"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"backend"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"filter"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"**/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"!*.log"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"**/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"!node_modules/.cache"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"!**/*.map"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"!**/*.md"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"directories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"output"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"../dist"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;extraResources&lt;/code&gt; copies the entire &lt;code&gt;backend/&lt;/code&gt; folder (including its &lt;code&gt;node_modules&lt;/code&gt;) into the packaged app's &lt;code&gt;resources/&lt;/code&gt; directory. At runtime, &lt;code&gt;process.resourcesPath&lt;/code&gt; points there. The original config had &lt;code&gt;!node_modules/**&lt;/code&gt; in the filter — that excluded backend deps and broke the embedded server at runtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bypassing Windows symlink restriction during build&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The challenge: &lt;code&gt;electron-builder&lt;/code&gt; downloads &lt;code&gt;winCodeSign-2.6.0.7z&lt;/code&gt; which contains macOS symlinks (&lt;code&gt;libcrypto.dylib&lt;/code&gt;, &lt;code&gt;libssl.dylib&lt;/code&gt;). Extracting it on Windows without Developer Mode fails with &lt;code&gt;Cannot create symbolic link: A required privilege is not held by the client.&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// frontend/node_modules/electron-builder/node_modules/&lt;/span&gt;
&lt;span class="c1"&gt;//   app-builder-lib/out/binDownload.js  (patched)&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doGetBin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;checksum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// winCodeSign archive contains macOS symlinks that fail to extract&lt;/span&gt;
  &lt;span class="c1"&gt;// on Windows without Developer Mode. Return the already-extracted&lt;/span&gt;
  &lt;span class="c1"&gt;// cache folder directly to skip the download+extract entirely.&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;winCodeSign&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt;   &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;os&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cacheBase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ELECTRON_BUILDER_CACHE&lt;/span&gt;
      &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;homedir&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AppData&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Local&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;electron-builder&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cache&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheBase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;winCodeSign&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;014093675&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;download-artifact&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;      &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--url&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checksum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--sha512&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;checksum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;executeAppBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This patch was applied to all three copies of &lt;code&gt;binDownload.js&lt;/code&gt; across &lt;code&gt;electron-builder&lt;/code&gt;, &lt;code&gt;dmg-builder&lt;/code&gt;, and &lt;code&gt;electron-builder-squirrel-windows&lt;/code&gt;. Combined with &lt;code&gt;"signAndEditExecutable": false&lt;/code&gt; in the build config to skip the &lt;code&gt;rcedit&lt;/code&gt; step that also triggers the same download.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In-memory LRU cache with TTL and pattern invalidation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The challenge: Dev.to API has rate limits. Every page load hitting the API directly would be slow and risk throttling. Need a fast in-process cache with automatic expiry and the ability to bust related keys when data changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// backend/server.js&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LRUCache&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;maxSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;CACHE_MAX&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_store&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_maxSize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;maxSize&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// LRU: delete and re-insert to move to end of Map iteration order&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ttl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_maxSize&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// evict the oldest entry (first key in Map)&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;ttl&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;invalidatePattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;re&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\*&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Usage: bust all article list caches when a reaction is posted&lt;/span&gt;
&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cacheKey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;article&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invalidatePattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;articles:*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Map&lt;/code&gt; preserves insertion order, so the first key is always the oldest — O(1) LRU eviction without a doubly-linked list. TTL is stored per-entry as an absolute expiry timestamp, checked on read.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dev.to API proxy with exponential back-off retry&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The challenge: network calls to Dev.to can fail transiently. Retrying immediately hammers the server. 4xx errors (bad request, unauthorized) should never be retried — only transient 5xx and network failures.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// backend/server.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;devtoAxios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;baseURL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;API_BASE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DEVTO_TIMEOUT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;API_HEADERS&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Per-request api-key injection without polluting the instance defaults&lt;/span&gt;
&lt;span class="nx"&gt;devtoAxios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;interceptors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cfg&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_apiKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api-key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_apiKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;delete&lt;/span&gt; &lt;span class="nx"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_apiKey&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cfg&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;withRetry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;retries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;RETRY_COUNT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;RETRY_DELAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;last&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;last&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="c1"&gt;// never retry client errors — they won't succeed on retry&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;delay&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 500ms, 1s, 2s&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;last&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;devtoGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;withRetry&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;devtoAxios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;...(&lt;/span&gt;&lt;span class="nx"&gt;apiKey&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_apiKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;apiKey&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}),&lt;/span&gt;
    &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;_apiKey&lt;/code&gt; trick lets each request carry its own Dev.to API key (from the logged-in user's header) without overwriting the shared Axios instance's default headers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JWT authentication with Supabase as user store&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The challenge: the app needs user accounts (to save API keys, bookmarks, etc.) but can't bundle a database. Supabase provides a hosted Postgres. The client must initialise lazily — if env vars are missing, the app should still run for unauthenticated browsing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// backend/server.js&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;_supabase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getSupabase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_supabase&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;_supabase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;SUPABASE_URL&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;SUPABASE_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// graceful degradation&lt;/span&gt;
  &lt;span class="nx"&gt;_supabase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;SUPABASE_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SUPABASE_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;autoRefreshToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;persistSession&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;_supabase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;authLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sb&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getSupabase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;sb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sendUnavail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Database not configured&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sb&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id, username, email, password_hash, devto_api_key&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;single&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sendError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HTTP_UNAUTH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid email or password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;valid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password_hash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sendError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HTTP_UNAUTH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid email or password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// fire-and-forget — don't block the login response&lt;/span&gt;
  &lt;span class="nx"&gt;sb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;last_login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}).&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;sendOk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;buildUserToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;bcrypt.compare&lt;/code&gt; is timing-safe — it takes the same time whether the user exists or not, preventing timing-based user enumeration attacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Response envelope compatibility&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The challenge: refactoring introduced a &lt;code&gt;{ success, data }&lt;/code&gt; wrapper around all responses. The frontend's &lt;code&gt;api.js&lt;/code&gt; does &lt;code&gt;const data = await res.json()&lt;/code&gt; and immediately uses &lt;code&gt;data&lt;/code&gt; as an array — &lt;code&gt;data.filter(...)&lt;/code&gt;, &lt;code&gt;data.map(...)&lt;/code&gt;. The wrapper broke every single page with "Unexpected response".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BROKEN — frontend does data.filter(...) which fails on { success, data }&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// FIXED — return raw data, frontend gets the array directly&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Error shape stays as { error: '...' } — frontend checks data.error&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sendError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// frontend/js/api.js (unchanged — this is what it expects)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cachedFetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ttl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// data is used directly as array — no .data unwrapping&lt;/span&gt;
  &lt;span class="nx"&gt;fetchCache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;exp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;ttl&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The lesson: when adding a backend in front of an existing frontend, match the existing API contract exactly. Changing the response shape is a breaking change even if the status code is still 200.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ReferenceError from temporal dead zone&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="nx"&gt;challenge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`server.js`&lt;/span&gt; &lt;span class="nx"&gt;grew&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="mi"&gt;1200&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="nx"&gt;added&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;different&lt;/span&gt; &lt;span class="nx"&gt;sections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;`app.use(loggerHelper.logRequest)`&lt;/span&gt; &lt;span class="nx"&gt;was&lt;/span&gt; &lt;span class="nx"&gt;placed&lt;/span&gt; &lt;span class="nx"&gt;at&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;284&lt;/span&gt; &lt;span class="nx"&gt;during&lt;/span&gt; &lt;span class="nx"&gt;an&lt;/span&gt; &lt;span class="nx"&gt;edit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;but&lt;/span&gt; &lt;span class="s2"&gt;`const app = express()`&lt;/span&gt; &lt;span class="nx"&gt;was&lt;/span&gt; &lt;span class="nx"&gt;at&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;991&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="c1"&gt;// line 284 — CRASHES: const is not hoisted, TDZ throws ReferenceError&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loggerHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ReferenceError: Cannot access 'app' before initialization&lt;/span&gt;

&lt;span class="c1"&gt;// ... 700 lines later ...&lt;/span&gt;

&lt;span class="c1"&gt;// line 991 — app is declared here&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1mb&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlencoded&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;extended&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;requestLogger&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loggerHelper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;logRequest&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// FIXED: moved here, after app exists&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;var&lt;/code&gt; would have hoisted and silently been &lt;code&gt;undefined&lt;/code&gt; at line 284, causing a different error (&lt;code&gt;TypeError: Cannot read properties of undefined&lt;/code&gt;). &lt;code&gt;const&lt;/code&gt; throws immediately and clearly. The fix is always to keep all &lt;code&gt;app.use()&lt;/code&gt; calls in one place, after &lt;code&gt;const app = express()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Layered architecture refactor&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The challenge: a single 200-line &lt;code&gt;server.js&lt;/code&gt; with routes, auth logic, caching, and HTTP client all mixed together. Adding features meant scrolling through everything. Testing any piece required the whole file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Before:                          After:
backend/                         backend/
  server.js  (200 lines,           config/
  everything mixed)                  app.config.js    (env vars)
                                     constants.js     (HTTP codes, keys)
                                     database.config.js (Supabase client)
                                   controllers/
                                     article.controller.js
                                     auth.controller.js
                                   services/
                                     devto-api.service.js (all API calls)
                                     auth.service.js      (register/login)
                                     cache.service.js     (TTL wrappers)
                                   middleware/
                                     auth.middleware.js
                                     error.middleware.js
                                   routes/
                                     article.routes.js
                                     auth.routes.js
                                   utils/
                                     cache.util.js
                                     http-client.util.js
                                     token.util.js
                                   server.js  (slim entry, ~40 lines)

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each layer has one job. Controllers handle HTTP in/out. Services contain business logic with no &lt;code&gt;req/res&lt;/code&gt; knowledge. Utils are pure functions. This means &lt;code&gt;devto-api.service.js&lt;/code&gt; can be tested without Express, and &lt;code&gt;auth.middleware.js&lt;/code&gt; can be swapped without touching routes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tech Stack &amp;amp; Skills&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;th&gt;Usage in This Project&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;Node.js v18+&lt;/td&gt;
&lt;td&gt;Server runtime embedded inside Electron main process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Desktop&lt;/td&gt;
&lt;td&gt;Electron 28&lt;/td&gt;
&lt;td&gt;Cross-platform desktop shell, window management, IPC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend Framework&lt;/td&gt;
&lt;td&gt;Express 4&lt;/td&gt;
&lt;td&gt;REST API server, middleware pipeline, route handling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP Client&lt;/td&gt;
&lt;td&gt;Axios&lt;/td&gt;
&lt;td&gt;Dev.to API proxy with interceptors and retry logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication&lt;/td&gt;
&lt;td&gt;JWT (jsonwebtoken)&lt;/td&gt;
&lt;td&gt;Stateless session tokens, Bearer auth middleware&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password Security&lt;/td&gt;
&lt;td&gt;bcryptjs&lt;/td&gt;
&lt;td&gt;Salted password hashing, timing-safe comparison&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;Supabase (Postgres)&lt;/td&gt;
&lt;td&gt;Hosted user store, lazy client initialization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Caching&lt;/td&gt;
&lt;td&gt;Custom LRU + TTL&lt;/td&gt;
&lt;td&gt;In-memory cache with pattern invalidation, O(1) eviction&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build Tool&lt;/td&gt;
&lt;td&gt;electron-builder&lt;/td&gt;
&lt;td&gt;Portable single &lt;code&gt;.exe&lt;/code&gt; packaging, extraResources bundling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Vanilla JS / HTML / CSS&lt;/td&gt;
&lt;td&gt;No framework, direct DOM manipulation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Environment&lt;/td&gt;
&lt;td&gt;dotenv&lt;/td&gt;
&lt;td&gt;Runtime env switching between dev and packaged paths&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Architecture Skills&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Skill&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Layered architecture&lt;/td&gt;
&lt;td&gt;config / controllers / services / middleware / routes / utils separation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Embedded server pattern&lt;/td&gt;
&lt;td&gt;Express running inside Electron main process — no child process or IPC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cache-aside pattern&lt;/td&gt;
&lt;td&gt;Check cache → miss → fetch API → populate cache → return&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exponential back-off retry&lt;/td&gt;
&lt;td&gt;Transient failures retried with &lt;code&gt;delay * 2^attempt&lt;/code&gt;, 4xx never retried&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Graceful degradation&lt;/td&gt;
&lt;td&gt;App runs without Supabase configured — auth disabled, browsing works&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;API contract preservation&lt;/td&gt;
&lt;td&gt;Backend response shape matched existing frontend without changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Middleware composition&lt;/td&gt;
&lt;td&gt;Auth, logging, validation, error handling as independent Express middleware&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build pipeline patching&lt;/td&gt;
&lt;td&gt;Patched &lt;code&gt;binDownload.js&lt;/code&gt; in 3 locations to bypass Windows symlink restriction&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Problems Solved&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Root Cause&lt;/th&gt;
&lt;th&gt;Solution&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Single &lt;code&gt;.exe&lt;/code&gt; with embedded backend&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;node_modules&lt;/code&gt; excluded from &lt;code&gt;extraResources&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Removed &lt;code&gt;!node_modules/**&lt;/code&gt; filter in build config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build fails on Windows&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;winCodeSign&lt;/code&gt; archive contains macOS symlinks&lt;/td&gt;
&lt;td&gt;Patched &lt;code&gt;doGetBin()&lt;/code&gt; + &lt;code&gt;signAndEditExecutable: false&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Unexpected response" on all pages&lt;/td&gt;
&lt;td&gt;Response wrapped in &lt;code&gt;{ success, data }&lt;/code&gt; envelope&lt;/td&gt;
&lt;td&gt;Returned raw data — matched existing frontend contract&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ReferenceError: Cannot access 'app'&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;app.use()&lt;/code&gt; called before &lt;code&gt;const app = express()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Moved all &lt;code&gt;app.use()&lt;/code&gt; calls after app initialization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev.to API rate limiting&lt;/td&gt;
&lt;td&gt;Every render hitting the API directly&lt;/td&gt;
&lt;td&gt;LRU cache with per-resource TTLs (1–10 min)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stale reaction counts after like&lt;/td&gt;
&lt;td&gt;Cache not invalidated on mutation&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;cache.invalidatePattern('articles:*')&lt;/code&gt; on POST/DELETE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User enumeration via timing&lt;/td&gt;
&lt;td&gt;Login returning early on unknown email&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;bcrypt.compare&lt;/code&gt; always runs regardless of user existence&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monolithic server hard to maintain&lt;/td&gt;
&lt;td&gt;All logic in one 200-line file&lt;/td&gt;
&lt;td&gt;Refactored into 6 layers, 20+ files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend path wrong in packaged app&lt;/td&gt;
&lt;td&gt;Dev path &lt;code&gt;../backend&lt;/code&gt; invalid after packaging&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;process.resourcesPath&lt;/code&gt; used in production, &lt;code&gt;__dirname&lt;/code&gt; in dev&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That project is technical, yes. But to me it is also personal.&lt;/p&gt;

&lt;p&gt;Because underneath all the implementation details is a very human belief: developers deserve tools that meet them with less friction, not more. We spend enough time wrestling complexity. Good software should not add ego to the burden.&lt;/p&gt;

&lt;p&gt;That is also what I think gender equity in tech should look like in practice. Not just opening the door and walking away, but designing better rooms once people get inside. Rooms where curiosity is not punished. Rooms where beginners are not treated like inconveniences. Rooms where expertise is shared in a way that multiplies confidence instead of hoarding status.&lt;/p&gt;

&lt;p&gt;I did not stay in tech because every experience was welcoming. I stayed because enough people, at crucial moments, chose to be generous.&lt;/p&gt;

&lt;p&gt;A patient senior engineer.&lt;br&gt;
A stranger answering a question online.&lt;br&gt;
A community that reminds you that even experienced developers still get stuck, still learn, still rewrite the same thing three times before pretending it was intentional.&lt;/p&gt;

&lt;p&gt;So when I think about the “echoes of experience,” I do not think only about the painful moments. I think about what answered them.&lt;/p&gt;

&lt;p&gt;Patience.&lt;br&gt;
Humor.&lt;br&gt;
Persistence.&lt;br&gt;
Community.&lt;/p&gt;

&lt;p&gt;And yes, sometimes coffee.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdm2a54jiimlomifxuse5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdm2a54jiimlomifxuse5.png" alt=" " width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I still have hard days. I still meet code that looks like it was written during a minor electrical storm. I still occasionally open a file and feel my soul leave my body for a second. But I no longer confuse that feeling with failure.&lt;/p&gt;

&lt;p&gt;Now I recognize it for what it usually is:&lt;/p&gt;

&lt;p&gt;the start of learning,&lt;br&gt;
the invitation to ask,&lt;br&gt;
and another chance to make this industry more human than I found it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try the project yourself&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to experience Always with Dev.to — Desktop Client directly, you can check the project here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/wvalencs/devTo-electron" rel="noopener noreferrer"&gt;https://github.com/wvalencs/devTo-electron&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run locally&lt;/p&gt;

&lt;p&gt;1.Clone the repository&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/wvalencs/devTo-electron.git
&lt;span class="nb"&gt;cd &lt;/span&gt;devTo-electron
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.Install dependencies&lt;/p&gt;

&lt;p&gt;Install dependencies for both the frontend and backend parts of the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;backend
npm &lt;span class="nb"&gt;install
cd&lt;/span&gt; ../frontend
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.Start the application in development mode&lt;/p&gt;

&lt;p&gt;Run the Electron frontend, which will start the embedded backend automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;backend
npm start
&lt;span class="nb"&gt;cd &lt;/span&gt;frontend
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.Build portable executable&lt;/p&gt;

&lt;p&gt;To generate the portable desktop app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;frontend
npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the build is complete, the packaged app will be available in the dist folder.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft3k6hor04bo7s2hyeu93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft3k6hor04bo7s2hyeu93.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want, next I can turn this into a true Dev.to-ready version with a stronger hook, cleaner section headers, and final tags.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>wecoded</category>
      <category>dei</category>
      <category>career</category>
    </item>
    <item>
      <title>Why Our AWS RDS Cost Suddenly Spiked and How We Saved ~40%</title>
      <dc:creator>Rokibul Hasan</dc:creator>
      <pubDate>Wed, 31 Dec 2025 15:57:24 +0000</pubDate>
      <link>https://forem.com/tirixa/why-our-aws-rds-cost-suddenly-spiked-and-how-we-saved-40-op6</link>
      <guid>https://forem.com/tirixa/why-our-aws-rds-cost-suddenly-spiked-and-how-we-saved-40-op6</guid>
      <description>&lt;p&gt;Our AWS RDS cost jumped unexpectedly over the last 2 days, even though usage and traffic were unchanged.&lt;/p&gt;

&lt;p&gt;What went wrong?&lt;/p&gt;

&lt;p&gt;After a deep dive, we found the root cause:&lt;br&gt;
👉 Our Reserved DB Instance (RI) had expired.&lt;/p&gt;

&lt;p&gt;Once the RI expired, the database automatically fell back to On-Demand pricing, which is significantly more expensive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We immediately purchased a new Reserved DB Instance matching:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;Instance class&lt;/li&gt;
&lt;li&gt;Multi-AZ&lt;/li&gt;
&lt;li&gt;Region&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was a billing-only change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No downtime&lt;/li&gt;
&lt;li&gt;No restarts&lt;/li&gt;
&lt;li&gt;No configuration changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The result&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;💰 ~30–40% reduction in DB instance cost&lt;/p&gt;

&lt;p&gt;📉 Monthly spend became predictable again&lt;/p&gt;

&lt;p&gt;⚡ Savings applied instantly&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key takeaway&lt;/strong&gt;&lt;br&gt;
RI expirations are silent, but their cost impact is immediate.&lt;/p&gt;

&lt;p&gt;Always monitor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RI expiration dates&lt;/li&gt;
&lt;li&gt;Cost Explorer anomalies&lt;/li&gt;
&lt;li&gt;Billing alerts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A missed RI renewal can cause instant cost spikes, even for stable workloads.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>aws</category>
      <category>awschallenge</category>
      <category>database</category>
    </item>
  </channel>
</rss>
