<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Raj Maharjan</title>
    <description>The latest articles on DEV Community by Raj Maharjan (@dubbyding).</description>
    <link>https://dev.to/dubbyding</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1160446%2F607f157f-50e4-431f-a45b-203e0888ce55.jpeg</url>
      <title>DEV Community: Raj Maharjan</title>
      <link>https://dev.to/dubbyding</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dubbyding"/>
    <language>en</language>
    <item>
      <title>So I Finally Tried to Understand Kubernetes</title>
      <dc:creator>Raj Maharjan</dc:creator>
      <pubDate>Wed, 01 Apr 2026 05:38:00 +0000</pubDate>
      <link>https://dev.to/dubbyding/so-i-finally-tried-to-understand-kubernetes-2a7e</link>
      <guid>https://dev.to/dubbyding/so-i-finally-tried-to-understand-kubernetes-2a7e</guid>
      <description>&lt;p&gt;Okay, so a few days ago I sat down and told myself — today I will finally understand Kubernetes. Not just know the name, not just say "yes, yes, K8s" in a meeting and nod. Actually understand it.&lt;/p&gt;

&lt;p&gt;I had been using Docker for a while. Build an image, run a container, push to a registry. That part I knew. But then people kept asking things like — "how do you handle scaling?" or "what happens when a container dies?" And I would just smile and say "hmm, good point."&lt;/p&gt;

&lt;p&gt;So I started reading, set up a small cluster on my laptop, and spent a few hours just playing around. Here is what I learned, told the way I wish someone had told me.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem Docker Doesn't Solve
&lt;/h2&gt;

&lt;p&gt;Docker gives you a nice box to put your app in. You know how it works, you know what's inside, you can run it anywhere. Wonderful.&lt;/p&gt;

&lt;p&gt;But the moment you move from your single laptop to actual servers — or even to a few containers talking to each other — questions start piling up:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Where do these containers actually run? What happens when one dies at 3am? How do they find each other on the network? How do I run three copies of the same service?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kubernetes is basically the answer to all of those questions at once. It is an open-source platform that runs your containers, watches over them, restarts them when they die, and lets them talk to each other. You just tell it &lt;strong&gt;what you want&lt;/strong&gt;, and it figures out the &lt;strong&gt;how&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think of it as an operating system — but for your whole data center instead of one machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Words You Need to Know
&lt;/h2&gt;

&lt;p&gt;Before anything makes sense, there are a few terms. I was scared of these at first because they sound very technical. But they are actually simple ideas with fancy names.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Term&lt;/th&gt;
&lt;th&gt;What it means&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cluster&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All the machines working together as one system — your "data center."&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A single machine (real or virtual) inside the cluster that actually runs your apps.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Pod&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The smallest thing K8s manages. Usually one container. Treat it as temporary — it can die anytime.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Deployment&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Says "I want 3 copies of this pod always running." Handles restarts and updates for you.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Service&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A stable address for your pods. Even if pods come and go, the Service address stays the same.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Namespace&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A folder inside your cluster. Useful for keeping dev, staging, prod separate.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  The Restaurant That Made It Click
&lt;/h2&gt;

&lt;p&gt;I read a lot of explanations. The one that finally made sense to me was a restaurant comparison. Let me tell it my own way.&lt;/p&gt;

&lt;p&gt;Imagine a restaurant. The whole restaurant is your &lt;strong&gt;Cluster&lt;/strong&gt;. The manager sitting in the back — who decides which cook does what, who watches the orders, who keeps track of everything — that is the &lt;strong&gt;Control Plane&lt;/strong&gt;. The actual cooking stations (grill, prep, fryer) are the &lt;strong&gt;Nodes&lt;/strong&gt;. Each dish being cooked right now is a &lt;strong&gt;Pod&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now here is the interesting part. When you order a "Chicken Burger" from the menu, you don't say "I want Chef Ramesh specifically to make it." You just say Chicken Burger. The menu item is always there, even if a cook leaves and a new one joins.&lt;/p&gt;

&lt;p&gt;That menu item is the &lt;strong&gt;Service&lt;/strong&gt;. It gives you a stable name to call, and it figures out which pod (cook) to send the work to. Even when pods die and new ones come up, the Service name stays the same.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Never talk to a Pod directly by its IP address. Pods are temporary — their IP can change or disappear. Always use a Service as the stable middleman.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  How Traffic Actually Flows
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────┐
│                     CLUSTER                         │
│  ┌──────────────┐     ┌───────────────────────────┐ │
│  │ Control Plane│────▶│       Worker Nodes        │ │
│  │ scheduler    │     │  ┌─────┐ ┌─────┐ ┌─────┐  │ │
│  │ etcd         │     │  │ Pod │ │ Pod │ │ Pod │  │ │
│  │ controllers  │     │  └─────┘ └─────┘ └─────┘  │ │
│  └──────────────┘     └───────────────────────────┘ │
└─────────────────────────────────────────────────────┘

Client ──▶ Service ──▶ Pod(s) ──▶ Container(s)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your request starts from outside, hits a &lt;strong&gt;Service&lt;/strong&gt;, and the Service decides which Pod handles it. You never call a Pod's IP directly.&lt;/p&gt;




&lt;h2&gt;
  
  
  kubectl — The Remote Control
&lt;/h2&gt;

&lt;p&gt;To talk to your cluster, you use a command-line tool called &lt;code&gt;kubectl&lt;/code&gt;. Think of it as a remote control. You press buttons, and the cluster does things.&lt;/p&gt;

&lt;p&gt;One thing that confused me early: &lt;strong&gt;&lt;code&gt;kubectl&lt;/code&gt; cannot create a cluster.&lt;/strong&gt; It can only talk to one that already exists. This is like — the TV remote can change channels, but it cannot build the TV.&lt;/p&gt;

&lt;p&gt;To create a cluster on your laptop for learning, you use a separate tool. The two most popular ones are &lt;code&gt;kind&lt;/code&gt; and &lt;code&gt;minikube&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;kind&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Runs K8s nodes as Docker containers. Very light.&lt;/td&gt;
&lt;td&gt;Quick setup, CI, already using Docker&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;minikube&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Spins up a local VM or Docker cluster with extra addons.&lt;/td&gt;
&lt;td&gt;Built-in dashboard, more feature-rich for learning&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I used &lt;code&gt;kind&lt;/code&gt; because it was the easiest to start. One command and you have a working cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a cluster named k8-learning&lt;/span&gt;
kind create cluster &lt;span class="nt"&gt;--name&lt;/span&gt; k8-learning

&lt;span class="c"&gt;# Check what's in it&lt;/span&gt;
kubectl get nodes
kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I ran &lt;code&gt;kubectl get nodes&lt;/code&gt;, I saw only one node called &lt;code&gt;k8-learning-control-plane&lt;/code&gt;. I panicked a little — "where are the other nodes?" But this is normal. With &lt;code&gt;kind&lt;/code&gt;'s default setup, you get one node that does everything. Fine for learning.&lt;/p&gt;




&lt;h2&gt;
  
  
  Writing My First Pod
&lt;/h2&gt;

&lt;p&gt;A Pod is just a YAML file describing what you want to run. Here is the simplest possible one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Pod&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;hello-pod&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:stable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply it and check on it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; pod.yaml
kubectl get pods
kubectl get pods &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few seconds later, your nginx container is running inside the cluster.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The Namespace Trap:&lt;/strong&gt; I kept running &lt;code&gt;kubectl get pods&lt;/code&gt; and seeing nothing, even after creating pods. The reason was namespaces. If you create something in a namespace called &lt;code&gt;production&lt;/code&gt; and forget to add &lt;code&gt;-n production&lt;/code&gt; to your command, K8s will look in the wrong place. Always specify the namespace.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Don't Use Bare Pods. Use Deployments.
&lt;/h2&gt;

&lt;p&gt;Here is a mistake I almost made. I was creating bare Pods and thinking "okay, I'm done." But bare Pods are not safe for real apps.&lt;/p&gt;

&lt;p&gt;If a bare Pod dies, it just... stays dead. Nothing brings it back. You have to do it manually. That is terrible for any real service.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;Deployment&lt;/strong&gt; is the right way. You tell it "I want 3 copies of this pod always running." If one dies, the Deployment notices and starts a new one. If you want to update the image, it does a rolling update — takes down the old ones slowly, brings up new ones, no downtime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bare Pods are for quick tests. Deployments are for anything you actually care about.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Mistakes I (Almost) Made
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;❌ &lt;strong&gt;Treating Pods like permanent things.&lt;/strong&gt; They are not. They die, they get restarted, their IP changes. Never rely on a Pod being there.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ &lt;strong&gt;Calling Pod IPs directly.&lt;/strong&gt; Pod IPs are temporary. Use a Service as a stable address. Always.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ &lt;strong&gt;Forgetting &lt;code&gt;-n&lt;/code&gt; for namespaces.&lt;/strong&gt; "Why can't I see my pod?!" — because you're looking in the wrong namespace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ &lt;strong&gt;Putting too many containers in one Pod.&lt;/strong&gt; One main container per Pod is the rule. Only combine containers if they truly need to share memory or files — like an app and a logging sidecar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;❌ &lt;strong&gt;Thinking kubectl creates clusters.&lt;/strong&gt; It doesn't. &lt;code&gt;kind&lt;/code&gt; or &lt;code&gt;minikube&lt;/code&gt; create the cluster. &lt;code&gt;kubectl&lt;/code&gt; just talks to it.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Want to Try It Yourself?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Install the tools&lt;/strong&gt;&lt;br&gt;
On macOS: &lt;code&gt;brew install kubectl&lt;/code&gt; and &lt;code&gt;brew install kind&lt;/code&gt;. On Linux, follow the official docs — both have simple install scripts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Create a cluster&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kind create cluster &lt;span class="nt"&gt;--name&lt;/span&gt; k8-learning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait a minute. You now have a working Kubernetes cluster on your laptop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Explore it&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl cluster-info
kubectl get nodes
kubectl get nodes &lt;span class="nt"&gt;-o&lt;/span&gt; wide
kubectl get pods
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Run a pod&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl run nginx &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nginx:stable &lt;span class="nt"&gt;--restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Never
kubectl get pods &lt;span class="nt"&gt;-o&lt;/span&gt; wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Clean up&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kind delete cluster &lt;span class="nt"&gt;--name&lt;/span&gt; k8-learning
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything gone, laptop happy.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;This was my first real day with Kubernetes. I went from "I know the name" to "I can actually run things and understand what is happening." That felt good.&lt;/p&gt;

&lt;p&gt;The next things I want to learn: how Deployments handle rolling updates, how Services work in different modes (ClusterIP, NodePort, LoadBalancer), and eventually how to set up something close to a real production setup.&lt;/p&gt;

&lt;p&gt;If you are a backend developer and you have been putting off learning this — don't. It is not as scary as it looks from outside. Set up &lt;code&gt;kind&lt;/code&gt;, run a pod, break something, fix it. That is how it clicks.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Thank you for reading.&lt;/em&gt; 🙏&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;A small note:&lt;/strong&gt; This is the beginning of a series where I write about things as I learn them — no expert voice, no pretending I know everything. Just a developer figuring things out and writing it down. Kubernetes is the current chapter. More blogs covering what I learn next will be coming soon — Deployments, Services, real configs, and whatever breaks along the way. Follow along if you are on a similar journey. 🚀&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>docker</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How I Used Next.js as Both the Frontend AND the Backend for My Microservices</title>
      <dc:creator>Raj Maharjan</dc:creator>
      <pubDate>Wed, 25 Mar 2026 05:07:58 +0000</pubDate>
      <link>https://dev.to/dubbyding/how-i-used-nextjs-as-both-the-frontend-and-the-backend-for-my-microservices-2ppm</link>
      <guid>https://dev.to/dubbyding/how-i-used-nextjs-as-both-the-frontend-and-the-backend-for-my-microservices-2ppm</guid>
      <description>&lt;p&gt;We are building a fintech product. The backend is a set of microservices — each service does one job, like handling payments, managing users, or dealing with authentication.&lt;/p&gt;

&lt;p&gt;For the frontend, we chose &lt;strong&gt;Next.js&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But here is the interesting part: Next.js ended up doing &lt;strong&gt;two jobs&lt;/strong&gt; in our architecture.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It renders the UI that the user sees — pages, components, everything visual.&lt;/li&gt;
&lt;li&gt;It also acts as a &lt;strong&gt;Backend for Frontend (BFF)&lt;/strong&gt; — a server layer that sits between the browser and our real microservices.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One Next.js project. Two responsibilities. This is the story of why I made that call, what it gave us, and what it cost us.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Does "Next.js as BFF" Actually Mean?
&lt;/h2&gt;

&lt;p&gt;Next.js is not just a frontend framework. It also lets you write &lt;strong&gt;API routes&lt;/strong&gt; — real server-side code that runs on a Node.js server, not in the browser.&lt;/p&gt;

&lt;p&gt;So our Next.js project has two parts living side by side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/app
  /dashboard        ← React pages (frontend)
  /profile          ← React pages (frontend)

/app/api
  /auth             ← API route (BFF — calls Auth microservice)
  /payments         ← API route (BFF — calls Payments microservice)
  /dashboard        ← API route (BFF — combines data from 3 services)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser loads the React pages from Next.js. When those pages need data, they call the Next.js API routes — not the microservices directly. The API routes then talk to the real microservices behind the scenes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser
  ↓  (loads page)
Next.js — React pages (frontend)
  ↓  (fetches data from)
Next.js — API routes (BFF)
  ↓  (calls)
Microservices (Auth / Payments / Users)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser never knows the microservices exist. It only ever talks to Next.js.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Made This Decision
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Security — Tokens Stay Out of the Browser
&lt;/h3&gt;

&lt;p&gt;When a user logs in, the real Auth microservice gives back an &lt;strong&gt;access token&lt;/strong&gt;. The normal thing to do is pass this token to the browser and store it in &lt;code&gt;localStorage&lt;/code&gt; or memory.&lt;/p&gt;

&lt;p&gt;But this is risky. If there is any XSS attack — malicious JavaScript running on your page — that token can be stolen and used to impersonate the user. In a fintech app, that is a serious problem.&lt;/p&gt;

&lt;p&gt;Because Next.js API routes run on the server, they can handle the token &lt;strong&gt;before&lt;/strong&gt; it ever reaches the browser. Here is the flow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Browser sends login details to the Next.js API route (&lt;code&gt;/api/auth/login&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The API route calls the real Auth microservice and gets the access token&lt;/li&gt;
&lt;li&gt;The API route converts that token into a &lt;strong&gt;secure, HTTP-only cookie&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The browser receives the cookie — it never sees the raw token&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HTTP-only cookies cannot be read by JavaScript at all. Even if an attacker runs code in the browser, they cannot steal the token because the browser never had it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// /app/api/auth/login/route.ts&lt;/span&gt;
&lt;span class="k"&gt;export&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;POST&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;Request&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;req&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;// Call the real microservice&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;accessToken&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;authService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&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="c1"&gt;// Convert to cookie — browser never sees the token&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookies&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;session&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;accessToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;httpOnly&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="na"&gt;secure&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;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;sameSite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;strict&lt;/span&gt;&lt;span class="dl"&gt;'&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="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="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&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 was the single biggest reason for the whole decision. Security first.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Dynamic Ads for External Websites
&lt;/h3&gt;

&lt;p&gt;Our product shows &lt;strong&gt;custom ads on third-party websites&lt;/strong&gt;. These ads are not static images — they need real-time data from our APIs to decide what to show to which user.&lt;/p&gt;

&lt;p&gt;The problem: a third-party website cannot call our internal microservices directly. That would expose internal URLs, create CORS headaches, and open security holes.&lt;/p&gt;

&lt;p&gt;With the Next.js BFF, the external website just calls a public-facing Next.js API route. That route handles all the internal API calls server-side and returns a clean response. The microservices stay completely hidden.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// /app/api/ads/route.ts — called by external websites&lt;/span&gt;
&lt;span class="k"&gt;export&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;GET&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;Request&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;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getUserFromCookie&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="c1"&gt;// Internal calls — the external world never sees these&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;adData&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;adsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPersonalizedAd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&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;Response&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;adData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exposed microservice URLs. No CORS issues. The outside world only knows about Next.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Combining Multiple Services Into One Response
&lt;/h3&gt;

&lt;p&gt;The dashboard page needs data from three different services — user profile, account balance, and recent transactions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Without BFF&lt;/strong&gt; — the browser makes 3 separate calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Browser → GET /users/me
Browser → GET /payments/balance
Browser → GET /transactions/recent
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three round trips. Slow. And the browser has to combine all the data itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With BFF&lt;/strong&gt; — the browser makes 1 call to the Next.js API route, which calls all three services in parallel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// /app/api/dashboard/route.ts&lt;/span&gt;
&lt;span class="k"&gt;export&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;GET&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;Request&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;transactions&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="nx"&gt;userService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMe&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nx"&gt;paymentsService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="nx"&gt;transactionService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRecent&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;Response&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;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;transactions&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;One call from the browser. One clean response. The browser does not care how many microservices were involved.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Difficulties
&lt;/h2&gt;

&lt;p&gt;This is where I have to be honest. This decision was not free.&lt;/p&gt;

&lt;h3&gt;
  
  
  Double Integration — The Biggest Pain
&lt;/h3&gt;

&lt;p&gt;Because Next.js is doing two jobs, every API endpoint has to be written &lt;strong&gt;twice&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Once in the real microservice&lt;/li&gt;
&lt;li&gt;Once as a Next.js API route that proxies or transforms the microservice call&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the backend has 20 endpoints, I have to write 20 Next.js API routes too. Some of them are almost identical to the microservice they are calling.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Microservice:  POST /auth/login   → returns { accessToken }
Next.js route: POST /api/auth/login → calls microservice, sets cookie
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This feels like redundancy — and it is. You are doing the integration work twice. This is the main trade-off of using your frontend framework as a BFF at the same time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next.js Becomes a Critical Point of Failure
&lt;/h3&gt;

&lt;p&gt;Before this architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Browser → Microservice
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Browser → Next.js → Microservice
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Next.js goes down, everything stops — the UI and the API layer both die at the same time. Before, a frontend bug would only break the UI. Now a Next.js server crash breaks the whole product.&lt;/p&gt;

&lt;p&gt;This means the Next.js deployment needs to be treated with the same care as a backend service — proper monitoring, health checks, and failover.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keeping the Two Layers in Sync
&lt;/h3&gt;

&lt;p&gt;When a microservice changes its API — a new field, a renamed key, a different response structure — the Next.js layer also needs to be updated. This could easily become a mess, but we have a clear process that keeps things manageable.&lt;/p&gt;

&lt;p&gt;Here is how it works in practice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The backend team updates their microservice&lt;/strong&gt; and gives me updated Swagger or Postman documentation showing what changed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I update the Next.js API route&lt;/strong&gt; (the BFF layer) to match the new microservice contract.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I update the frontend&lt;/strong&gt; — the React pages and components — to use the new data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Steps 2 and 3 sound like extra work, but here is where having Next.js handle both roles actually helps: because the API routes and the React pages live in the &lt;strong&gt;same project&lt;/strong&gt;, I can define a &lt;strong&gt;shared TypeScript interface&lt;/strong&gt; for the response once and use it in both places.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// types/dashboard.ts — defined once, used everywhere in the same project&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;DashboardResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nl"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transactions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Transaction&lt;/span&gt;&lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// /app/api/dashboard/route.ts — BFF layer uses it&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DashboardResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/types/dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// /app/dashboard/page.tsx — frontend also uses the same type&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DashboardResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@/types/dashboard&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;If the microservice changes and I update the interface, TypeScript immediately shows me every place in the frontend that is now broken. I do not have to search manually — the compiler tells me exactly what to fix.&lt;/p&gt;

&lt;p&gt;So yes, there is still sync work to do whenever the backend team ships a change. But the tight loop between the BFF routes and the UI — all in one project, all sharing types — makes that sync much faster than if they were separate codebases.&lt;/p&gt;

&lt;h3&gt;
  
  
  "Wait, Is This Frontend or Backend?"
&lt;/h3&gt;

&lt;p&gt;New developers joining the project often get confused at first. They see API routes inside a Next.js project and are not sure what the boundary is.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why is there auth logic in the frontend project?"&lt;br&gt;
"Should I add new business logic here or in the microservice?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These questions are completely valid. The answer needs to be written down clearly — the Next.js API routes are the BFF layer, not a second backend. They handle session management, data aggregation, and the public API surface. Business logic lives in the microservices.&lt;/p&gt;

&lt;p&gt;Without clear documentation, this confusion slows down new team members.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Learned From My First Architecture Decision
&lt;/h2&gt;

&lt;p&gt;This was the first time I made a real architectural call on a production product. Here is what I took away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next.js is genuinely good at this dual role.&lt;/strong&gt; It was designed to run server-side code. API routes are first-class citizens. Using them as a BFF is not a hack — it is a well-supported pattern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The security benefit is real and hard to get another way.&lt;/strong&gt; The token-to-cookie conversion needs a server. If you are using Next.js for the frontend anyway, using its API routes for this is practical and keeps your stack simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The redundancy is the real cost.&lt;/strong&gt; Every time I add a new microservice endpoint, I feel the double integration work. It is not a one-time pain. It is ongoing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Document the "why", not just the "what".&lt;/strong&gt; The code shows &lt;em&gt;what&lt;/em&gt; the system does. Only documentation explains &lt;em&gt;why&lt;/em&gt; Next.js is doing API work at all. Without that, every new developer has to rediscover the reasoning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;There is no perfect architecture.&lt;/strong&gt; Every decision trades one problem for another. This decision traded simplicity for security and cleaner data access. Knowing that trade-off clearly — instead of just copying a pattern from a blog post — is what made it feel like a real decision.&lt;/p&gt;




&lt;h2&gt;
  
  
  Would I Do It Again?
&lt;/h2&gt;

&lt;p&gt;Yes — for this project.&lt;/p&gt;

&lt;p&gt;The security layer was non-negotiable for a fintech product. The dynamic ads feature needed a server in the middle. And combining multiple API calls into one response has kept the React components much simpler.&lt;/p&gt;

&lt;p&gt;But if I was starting a small personal project? I would not add this complexity. The double integration work is a real ongoing cost, and it only makes sense when the benefits — security, abstraction, external API surface — actually justify it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you used Next.js as both the frontend and the BFF in the same project? I would love to know how you handled the double integration problem — did you auto-generate the routes, or did you draw a strict line somewhere about what logic belongs where? Drop it in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>nextjs</category>
      <category>backendforfrontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Building Maintainable Backends with Port-Adapter Architecture in NestJS</title>
      <dc:creator>Raj Maharjan</dc:creator>
      <pubDate>Thu, 15 Jan 2026 05:30:27 +0000</pubDate>
      <link>https://dev.to/dubbyding/building-maintainable-backends-with-port-adapter-architecture-in-nestjs-40ka</link>
      <guid>https://dev.to/dubbyding/building-maintainable-backends-with-port-adapter-architecture-in-nestjs-40ka</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Port-Adapter Architecture helps keep business logic separate from infrastructure like databases and external services, making your NestJS app easier to test and change. Use it only where flexibility matters, not everywhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When we start backend development, most of us write code like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Controller calls Service&lt;/li&gt;
&lt;li&gt;Service directly talks to Database&lt;/li&gt;
&lt;li&gt;Service also calls email, SMS, payment, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This works fine at the beginning. But as the project grows, things slowly become messy. One small change breaks many places. Testing becomes hard. New developers feel lost.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Port-Adapter Architecture&lt;/strong&gt; (also known as &lt;strong&gt;Hexagonal Architecture&lt;/strong&gt;) helps. It is not magic and not mandatory everywhere, but when used correctly, it makes backend code clean, understandable, and future-proof.&lt;/p&gt;

&lt;p&gt;In this article, we will understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What Port-Adapter Architecture really is (in simple words)&lt;/li&gt;
&lt;li&gt;Why and when to use it&lt;/li&gt;
&lt;li&gt;How it compares to other approaches&lt;/li&gt;
&lt;li&gt;A clear folder structure&lt;/li&gt;
&lt;li&gt;When NOT to use ports&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What Problem Are We Actually Solving?
&lt;/h2&gt;

&lt;p&gt;Imagine this service code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ProductService&lt;/span&gt;
&lt;span class="k"&gt;await&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;productModel&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&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;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email-service/send&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;redis&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;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problems here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database logic inside service&lt;/li&gt;
&lt;li&gt;External API logic inside service&lt;/li&gt;
&lt;li&gt;Hard to test&lt;/li&gt;
&lt;li&gt;Hard to replace MongoDB or email provider&lt;/li&gt;
&lt;li&gt;Too many responsibilities in one place&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates tight coupling. Tight coupling makes future changes painful.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Port-Adapter Architecture (Hexagonal Architecture)?
&lt;/h2&gt;

&lt;p&gt;Port-Adapter Architecture separates &lt;strong&gt;thinking&lt;/strong&gt; from &lt;strong&gt;doing&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Port&lt;/strong&gt; = What the application needs (interface)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adapter&lt;/strong&gt; = How it is actually done (real implementation)&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;"I need to save a product" → Port&lt;/li&gt;
&lt;li&gt;"I save it using MongoDB" → Adapter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If tomorrow you want PostgreSQL, you only change the adapter. Business logic stays the same.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Port-Adapter vs Other Common Approaches?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Traditional Service → Repository (No Ports)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Controller → Service → Repository
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach is completely fine for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Small applications&lt;/li&gt;
&lt;li&gt;MVPs&lt;/li&gt;
&lt;li&gt;Side projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it becomes a problem when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Service depends on many external systems&lt;/li&gt;
&lt;li&gt;Testing requires mocking many things&lt;/li&gt;
&lt;li&gt;You want to replace implementations&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. Clean Architecture
&lt;/h3&gt;

&lt;p&gt;Clean Architecture is powerful, but:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Too many layers&lt;/li&gt;
&lt;li&gt;Too much boilerplate&lt;/li&gt;
&lt;li&gt;Hard for beginners&lt;/li&gt;
&lt;li&gt;Slower development for small teams&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3. Why Port-Adapter is a Good Balance
&lt;/h3&gt;

&lt;p&gt;Port-Adapter gives:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear boundaries&lt;/li&gt;
&lt;li&gt;Less coupling&lt;/li&gt;
&lt;li&gt;Easier testing&lt;/li&gt;
&lt;li&gt;Flexibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without being too complex or academic.&lt;/p&gt;




&lt;h2&gt;
  
  
  Important Rule: Ports Are NOT Required for Everything
&lt;/h2&gt;

&lt;p&gt;This is very important.&lt;/p&gt;

&lt;p&gt;Do NOT create ports for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple CRUD repositories&lt;/li&gt;
&lt;li&gt;Internal helper services&lt;/li&gt;
&lt;li&gt;Utility functions&lt;/li&gt;
&lt;li&gt;Logic that will never change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use ports for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;External services (email, SMS, payment)&lt;/li&gt;
&lt;li&gt;Cross-module dependencies&lt;/li&gt;
&lt;li&gt;Business-critical operations&lt;/li&gt;
&lt;li&gt;Things that may change in the future&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Architecture should reduce complexity, not increase it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Beginner-Friendly Folder Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
│
├── product/
│   ├── controllers/
│   │   └── product.controller.ts
│   │
│   ├── services/
│   │   └── product.service.ts
│   │
│   ├── ports/
│   │   └── product.port.ts
│   │
│   ├── repositories/
│   │   └── product.repository.ts
│   │
│   ├── dto/
│   │   ├── create-product.dto.ts
│   │   └── update-product.dto.ts
│   │
│   ├── schemas/
│   │   └── product.schema.ts
│   │
│   ├── product.tokens.ts
│   └── product.module.ts
│
├── inventory/
│   ├── ports/
│   ├── services/
│   └── inventory.module.ts
│
├── notification/
│   ├── ports/
│   ├── services/
│   └── notification.module.ts
│
└── common/
    ├── base/
    ├── utils/
    └── constants/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why This Structure Works
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Easy for new developers to understand&lt;/li&gt;
&lt;li&gt;Clear separation of responsibilities&lt;/li&gt;
&lt;li&gt;Business logic is easy to find&lt;/li&gt;
&lt;li&gt;Infrastructure code is isolated&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Where Ports Make the Most Sense
&lt;/h2&gt;

&lt;p&gt;A very common and practical example is &lt;strong&gt;payment or transaction handling&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine your application needs to process payments. Today you might use &lt;strong&gt;Stripe&lt;/strong&gt;, but tomorrow the business may ask to support another payment partner like &lt;strong&gt;Khalti&lt;/strong&gt;, &lt;strong&gt;Esewa&lt;/strong&gt;, or any other gateway.&lt;/p&gt;

&lt;p&gt;If you directly write Stripe code inside your service, changing the payment provider later will be painful and risky.&lt;/p&gt;

&lt;p&gt;This is where a &lt;strong&gt;port&lt;/strong&gt; makes perfect sense.&lt;/p&gt;

&lt;h3&gt;
  
  
  Payment Port Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// payment.port.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PaymentPort&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;PaymentResult&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Stripe Adapter
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StripePaymentAdapter&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;PaymentPort&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Stripe-specific implementation&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Another Payment Adapter (Future)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EsewaPaymentAdapter&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;PaymentPort&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Esewa-specific implementation&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Service Using the Port
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PAYMENT_SERVICE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;paymentService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PaymentPort&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;Now your business logic does not care whether the payment is done by Stripe, Esewa, or any other provider. You can switch implementations from the module without touching the service code.&lt;/p&gt;

&lt;p&gt;This is an ideal and real-world use case for Port-Adapter Architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  When You Should Avoid Ports
&lt;/h2&gt;

&lt;p&gt;If your code is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&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;userRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Repository is local&lt;/li&gt;
&lt;li&gt;No external dependency&lt;/li&gt;
&lt;li&gt;No plan to replace it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then do not create a port. Keep it simple.&lt;/p&gt;




&lt;h2&gt;
  
  
  Simple Mental Model
&lt;/h2&gt;

&lt;p&gt;Before creating a port, ask:&lt;/p&gt;

&lt;p&gt;"Will I ever want to replace or mock this?"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Yes → Use a port&lt;/li&gt;
&lt;li&gt;No → Do not use a port&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Port-Adapter Architecture is a tool, not a rule.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Project is growing&lt;/li&gt;
&lt;li&gt;Multiple developers are working together&lt;/li&gt;
&lt;li&gt;Business logic is important&lt;/li&gt;
&lt;li&gt;Testing matters&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Application is small&lt;/li&gt;
&lt;li&gt;Logic is simple&lt;/li&gt;
&lt;li&gt;Abstraction adds confusion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In NestJS, this pattern fits naturally and helps keep code clean without becoming too complex. Start small and apply it only where it makes sense.&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>backend</category>
      <category>architecture</category>
    </item>
    <item>
      <title>GIL in Python: What is it and Why Does it Matter?</title>
      <dc:creator>Raj Maharjan</dc:creator>
      <pubDate>Fri, 23 May 2025 19:18:51 +0000</pubDate>
      <link>https://dev.to/dubbyding/gil-in-python-what-is-it-and-why-does-it-matter-d5p</link>
      <guid>https://dev.to/dubbyding/gil-in-python-what-is-it-and-why-does-it-matter-d5p</guid>
      <description>&lt;p&gt;The Global Interpreter Lock (GIL) is a lock that makes sure only one thread runs Python code at a time. It helps prevent problems when Python works with memory, but it also means Python can't fully use multiple cores of a CPU at once.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the GIL?
&lt;/h2&gt;

&lt;p&gt;The GIL is a lock used by Python to ensure that only one thread can run Python code at a time. This is necessary because Python’s memory management isn’t safe for multiple threads to access at once.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does the GIL Exist?
&lt;/h2&gt;

&lt;p&gt;The GIL exists to prevent issues with memory when multiple threads try to access Python objects at the same time. Python's memory management system isn't built for multi-threading, so the GIL makes sure it’s safe to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference Counting and Garbage Collection
&lt;/h2&gt;

&lt;p&gt;In Python, memory is managed by two things: reference counting and garbage collection. These methods work together to automatically clean up unused objects and free up memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference Counting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every object in Python has a reference count that tracks how many references point to it. When no one is using an object (i.e., its reference count becomes zero), Python automatically removes it from memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of Reference Counting&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;Step&lt;/th&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Reference Count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create an object&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;a = [1, 2, 3]&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A new list object is created and assigned to &lt;strong&gt;a&lt;/strong&gt;.&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Assign to another variable&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;b = a&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The reference count increases because &lt;strong&gt;b&lt;/strong&gt; now points to the same list object as &lt;strong&gt;a&lt;/strong&gt;.&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete one reference&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;del a&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Deleting &lt;strong&gt;a&lt;/strong&gt; decreases the reference count, leaving only &lt;strong&gt;b&lt;/strong&gt; pointing to the list.&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete the last reference&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;del b&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Both references are deleted, and the list object is deallocated.&lt;/td&gt;
&lt;td&gt;0 (deallocated)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import sys

a = [1, 2, 3]  # Create a list object
print(sys.getrefcount(a))  # Output: 2 (one reference by 'a', another by getrefcount)

b = a  # Assign to another variable
print(sys.getrefcount(a))  # Output: 3 (now referenced by 'a', 'b', and getrefcount)

del a  # Remove one reference
print(sys.getrefcount(b))  # Output: 2 (now only referenced by 'b' and getrefcount)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example shows how the reference count changes when we create and delete references to an object. Once there are no references left, Python removes the object from memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Garbage Collection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Reference counting works well, but it can’t handle cyclic references. This happens when objects reference each other in a loop, and the reference count never reaches zero. To deal with this, Python has a garbage collector that looks for these loops and frees the memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How It Works&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When the garbage collector finds cyclic references, it removes them from memory.&lt;/li&gt;
&lt;li&gt;The gc module allows you to control and work with garbage collection in Python.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import gc

class Node:
    def __init__(self, value):
        self.value = value
        self.next = None

node1 = Node(1)
node2 = Node(2)
node1.next = node2
node2.next = node1  # Creates a cycle

# Even if 'node1' and 'node2' are deleted, they will not be freed immediately
# because their reference counts never drop to zero.
del node1
del node2

# Manually run the garbage collector
gc.collect()  # Forces garbage collection to clean up cyclic references
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, even though we delete node1 and node2, the cycle between them stops their reference count from reaching zero. The garbage collector clears them when we run gc.collect().&lt;/p&gt;

&lt;h2&gt;
  
  
  Real World Analogy
&lt;/h2&gt;

&lt;p&gt;Imagine a busy kitchen with several chefs (threads) and many cooking stations (CPU cores). The kitchen has enough space for many chefs to work at once, but there is a rule: only one chef can use the recipe book (the Python interpreter) at a time.&lt;/p&gt;

&lt;p&gt;Here’s how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chef 1 starts cooking and picks up the recipe book.&lt;/li&gt;
&lt;li&gt;The other chefs have to wait, even if stations are free, because only one chef can use the recipe book at a time.&lt;/li&gt;
&lt;li&gt;Once Chef 1 finishes, they put the recipe book down for the next chef to use.&lt;/li&gt;
&lt;li&gt;This cycle continues, making sure no two chefs are working at the same time, even though the kitchen could handle more.&lt;/li&gt;
&lt;li&gt;This "one chef at a time" rule is like Python’s GIL. It makes things safe but doesn’t use resources fully, especially for tasks that need a lot of processing power.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why is the GIL a Problem?
&lt;/h2&gt;

&lt;p&gt;The GIL can slow down programs that need a lot of CPU power or use multiple threads. It stops Python from using multiple CPU cores at once, which can hurt performance on multi-core processors.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import threading
import time

def task(name):
    for i in range(5):
        print(f"{name} is working on step {i + 1}")
        time.sleep(0.1)  # Simulate work

# Create two threads
thread1 = threading.Thread(target=task, args=("Chef 1",))
thread2 = threading.Thread(target=task, args=("Chef 2",))

# Start the threads
thread1.start()
thread2.start()

# Wait for threads to finish
thread1.join()
thread2.join()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Chef 1 is working on step 1
Chef 2 is working on step 1
Chef 1 is working on step 2
Chef 2 is working on step 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How Can I Avoid the GIL?
&lt;/h2&gt;

&lt;p&gt;There are a few ways to avoid the GIL’s limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;multi-processing&lt;/strong&gt; instead of multi-threading.
-Use a Python version that doesn’t have the GIL, like Jython or PyPy. But keep in mind that these don’t support popular libraries like &lt;strong&gt;numpy&lt;/strong&gt; and &lt;strong&gt;pandas&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is the Future of the GIL?
&lt;/h2&gt;

&lt;p&gt;As of &lt;a href="https://peps.python.org/pep-0703/" rel="noopener noreferrer"&gt;PEP703&lt;/a&gt;, the GIL may become optional in the future, or even removed. But for now, if you want to avoid GIL issues, it’s best to use multi-processing or consider Python implementations that don’t use the GIL.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the Impact of the GIL on My Program?
&lt;/h2&gt;

&lt;p&gt;The GIL affects your program depending on what you are doing. If your program does a lot of CPU-heavy work, like rendering games or running calculations, the GIL can slow it down. On the other hand, if your program does a lot of I/O work, like database queries or loading files, the GIL will have less impact.&lt;/p&gt;

&lt;p&gt;In libraries like &lt;strong&gt;numpy&lt;/strong&gt; and &lt;strong&gt;pandas&lt;/strong&gt;, the GIL is not an issue because they are written in C/C++ and don’t rely on Python’s memory management.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Some Alternatives to the GIL?
&lt;/h2&gt;

&lt;p&gt;Some alternatives to the GIL include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PyPy&lt;/li&gt;
&lt;li&gt;jython&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>gil</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Handling WebSockets in React Native with Socket.IO</title>
      <dc:creator>Raj Maharjan</dc:creator>
      <pubDate>Fri, 23 May 2025 07:39:27 +0000</pubDate>
      <link>https://dev.to/dubbyding/handling-websockets-in-react-native-with-socketio-49e0</link>
      <guid>https://dev.to/dubbyding/handling-websockets-in-react-native-with-socketio-49e0</guid>
      <description>&lt;p&gt;WebSockets are essential for creating interactive, real-time apps, but using them in a mobile setting like React Native presents difficulties due to poor internet, disconnected connections, and retries.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is socket.io?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://socket.io/docs/v4/#:~:text=Socket.IO%20is%20a%20library,WebSocket" rel="noopener noreferrer"&gt;Socket.IO&lt;/a&gt; is a library that enables low-latency, bidirectional and event-based communication between a client and a server. Socket.IO manages events, retries, and connection management, making WebSocket implementation easier. It is an great option for guaranteeing good event delivery as it also supports acknowledgements.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Setting Up the Project
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Install Dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, create a React Native project and install the required dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx @react-native-community/cli@latest init SocketIOExample
cd SocketIOExample
npm install socket.io-client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Creating the Socket Context
&lt;/h2&gt;

&lt;p&gt;To make the socket instance globally accessible, we’ll use a React Context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SocketContext.tsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, {createContext, useContext, useEffect, useRef} from 'react';

import {AppState} from 'react-native';
import {io, Socket} from 'socket.io-client';

// Define the context type
interface Message {
  id: string;
  text: string;
}

interface SocketContextType {
  socket: Socket | null;
  isConnected: boolean;
  messages: Message[];
  setMessage: React.Dispatch&amp;lt;React.SetStateAction&amp;lt;Message[]&amp;gt;&amp;gt;;
}

const SocketContext = createContext&amp;lt;SocketContextType | undefined&amp;gt;(undefined);

export const SocketProvider: React.FC&amp;lt;{children: React.ReactNode}&amp;gt; = ({
  children,
}) =&amp;gt; {
  const socketRef = useRef&amp;lt;Socket | null&amp;gt;(null);
  const [isConnected, setIsConnected] = React.useState(false);
  const [message, setMessage] = React.useState&amp;lt;Message[]&amp;gt;([]);

  useEffect(() =&amp;gt; {
    socketRef.current = io('http://localhost:3000', {
      reconnection: true, // Enable automatic reconnection
      reconnectionAttempts: Infinity, // Number of reconnection attempts
      reconnectionDelay: 1000, // Initial delay between reconnection attempts (ms)
      reconnectionDelayMax: 10000, // Maximum delay between reconnection attempts (ms)
      timeout: 10000, // Connection timeout (ms)
      autoConnect: true, // Automatically connect to the server when the component mounts
      forceNew: false, // Do not force a new connection on each connection attempt
    });

    const socket = socketRef.current;

    const handleAppStateChange = (nextAppState: string) =&amp;gt; {
      if (nextAppState === 'active') {
        socket?.connect();
      } else if (nextAppState === 'background') {
        socket?.disconnect();
      }
    };

    const appStateSubscription = AppState.addEventListener(
      'change',
      handleAppStateChange,
    );

    socket.on('connect', () =&amp;gt; {
      console.log('Connected to server');
      setIsConnected(true);
    });

    socket.on('disconnect', reason =&amp;gt; {
      console.warn('Disconnected:', reason);
      setIsConnected(false);
    });

    socket.on('connect_error', error =&amp;gt; {
      console.error('Connection error:', error.message);
    });

    socket.on('message', data =&amp;gt; {
      if (data &amp;amp;&amp;amp; data.id &amp;amp;&amp;amp; data.text) {
        setMessage(prevValue =&amp;gt; [...prevValue, data]);
      } else {
        console.error('Invalid message data:', data);
      }
    });

    return () =&amp;gt; {
      socket.disconnect();
      socket.removeAllListeners();
      appStateSubscription.remove();
    };
  }, []);

  return (
    &amp;lt;SocketContext.Provider
      value={{
        socket: socketRef.current,
        isConnected,
        messages: message,
        setMessage,
      }}&amp;gt;
      {children}
    &amp;lt;/SocketContext.Provider&amp;gt;
  );
};

export const useSocket = (): SocketContextType =&amp;gt; {
  const context = useContext(SocketContext);
  if (!context) {
    throw new Error('useSocket must be used within a SocketProvider');
  }
  return context;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatically manages connection and disconnection.&lt;/li&gt;
&lt;li&gt;Provides a global socket instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Handling Acknowledgements and Event Queue
&lt;/h2&gt;

&lt;p&gt;Acknowledgements ensure the server processes your events. We’ll also handle retries and queue events when disconnected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useSocketInstance.tsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import {useCallback, useEffect, useState} from 'react';
import {useSocket} from './SocketContext';

interface EventQueueItem {
  eventName: string;
  eventData: any;
  retryCount: number;
}

export const useSocketInstance = () =&amp;gt; {
  const {socket, isConnected, messages: message, setMessage} = useSocket();
  const [eventQueue, setEventQueue] = useState&amp;lt;EventQueueItem[]&amp;gt;([]);

  const MAX_RETRIES = 3;
  const ACK_TIMEOUT = 5000; // Timeout in ms

  const addToQueue = (eventName: string, eventData: any, retryCount = 0) =&amp;gt; {
    setEventQueue(prev =&amp;gt; [...prev, {eventName, eventData, retryCount}]);
  };

  const emitWithAck = useCallback(
    async (
      eventName: string,
      eventData: any,
      retryCount = 0,
    ): Promise&amp;lt;void&amp;gt; =&amp;gt; {
      if (!socket || !isConnected) {
        console.warn(`Socket disconnected. Queuing event: ${eventName}`);
        addToQueue(eventName, eventData, retryCount);
        return;
      }

      try {
        const response = await socket
          .timeout(ACK_TIMEOUT)
          .emitWithAck(eventName, eventData);
        if (response.status === 'ok') {
          console.log(`Event ${eventName} delivered successfully.`);
        } else {
          console.error(`Server error for event ${eventName}:`, response.error);
          throw new Error(response.error);
        }
      } catch (error) {
        console.warn(`Ack failed for event ${eventName}:`, error);
        if (retryCount &amp;lt; MAX_RETRIES) {
          console.log(
            `Retrying event ${eventName} (${retryCount + 1}/${MAX_RETRIES})`,
          );
          addToQueue(eventName, eventData, retryCount + 1);
        } else {
          console.error(
            `Event ${eventName} failed after ${MAX_RETRIES} retries.`,
          );
          // Notify the caller about the failure
          throw new Error(
            `Event ${eventName} failed after ${MAX_RETRIES} retries.`,
          );
        }
      }
    },
    [isConnected, socket],
  );

  const processQueue = useCallback(() =&amp;gt; {
    if (socket &amp;amp;&amp;amp; isConnected) {
      eventQueue.forEach(({eventName, eventData, retryCount}) =&amp;gt; {
        emitWithAck(eventName, eventData, retryCount);
      });
      setEventQueue([]); // Clear the queue after processing
    }
  }, [emitWithAck, eventQueue, isConnected, socket]);

  useEffect(() =&amp;gt; {
    if (isConnected) {
      processQueue();
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isConnected, eventQueue]); // This will rerun the effect when either the socket is connected and when there is queue to run

  return {emitWithAck, isConnected, message, setMessage};
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Integrating into the App
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;App.tsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import {SocketProvider} from './SocketContext';
import ChatScreen from './ChatScreen';

function App(): React.JSX.Element {
  return (
    &amp;lt;SocketProvider&amp;gt;
      &amp;lt;ChatScreen /&amp;gt;
    &amp;lt;/SocketProvider&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;ChatScreen.tsx&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, {useState} from 'react';
import {View, TextInput, Button, StyleSheet, Alert, Text} from 'react-native';
import {useSocketInstance} from './useSocketInstance';

const ChatScreen = () =&amp;gt; {
  const {emitWithAck, isConnected, message} = useSocketInstance();
  const [currentMessage, setCurrentMessage] = useState('');

  const sendMessage = () =&amp;gt; {
    if (currentMessage.trim()) {
      emitWithAck('sendMessage', {currentMessage}).catch(error =&amp;gt; {
        console.error('Error sending message:', error);
        // Handle the error, e.g., display an error message to the user
        Alert.alert('Error sending message: ' + error.message);
      });
      setCurrentMessage('');
    }
  };

  return (
    &amp;lt;View style={styles.container}&amp;gt;
      {message.map(value =&amp;gt; (
        &amp;lt;Text key={value.id}&amp;gt;{value.text}&amp;lt;/Text&amp;gt;
      ))}
      &amp;lt;TextInput
        value={currentMessage}
        onChangeText={setCurrentMessage}
        placeholder="Type a message"
        style={styles.input}
      /&amp;gt;
      &amp;lt;Button
        title="Send Message"
        onPress={sendMessage}
        disabled={!isConnected}
      /&amp;gt;
    &amp;lt;/View&amp;gt;
  );
};

const styles = StyleSheet.create({
  container: {padding: 20},
  input: {
    borderWidth: 1,
    borderColor: '#ccc',
    borderRadius: 5,
    marginBottom: 10,
    padding: 10,
  },
});

export default ChatScreen;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;This setup ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reliable Event Delivery: Acknowledgements with retries and timeouts ensure messages are not lost.&lt;/li&gt;
&lt;li&gt;Reconnection Management: Automatically processes queued events when the connection is restored.&lt;/li&gt;
&lt;li&gt;Global Access: A centralized socket context simplifies application logic.&lt;/li&gt;
&lt;li&gt;With this robust approach, your React Native app can handle WebSocket communication even under unreliable network conditions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Github Link: &lt;a href="https://github.com/dubbyding/react-native-socket" rel="noopener noreferrer"&gt;https://github.com/dubbyding/react-native-socket&lt;/a&gt;&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>websockets</category>
      <category>socket</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Code Documentation: Necessity or a Waste of Time?</title>
      <dc:creator>Raj Maharjan</dc:creator>
      <pubDate>Tue, 03 Oct 2023 08:27:10 +0000</pubDate>
      <link>https://dev.to/dubbyding/code-documentation-necessity-or-a-waste-of-time-5bjd</link>
      <guid>https://dev.to/dubbyding/code-documentation-necessity-or-a-waste-of-time-5bjd</guid>
      <description>&lt;p&gt;When I began my first internship after graduating from engineering school, everyone kept saying how important documentation was for coding. I couldn't help but wonder, 'Why? I already understand what I'm doing,' 'Is it a waste of time?' or 'I could write more code instead of documenting.' Maybe not everyone feels this way, especially experienced developers who've struggled for days or even weeks trying to understand code from others who didn't include any documentation realizing more and more the importance of documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation?
&lt;/h2&gt;

&lt;p&gt;Documentation may have different definitions if you look at different fields even in IT. Design documentation, Project Management Documentation, Programming Documentation, etc. Each holds a different section of importance in a project. For example for code, It’s definition is, &lt;a href="(https://swimm.io/learn/code-documentation/code-documentation-benefits-challenges-and-tips-for-success)"&gt;“It is a collection of documents and code comments explaining how code works and how to use it.”&lt;/a&gt; There may be standard in place that helps to make documentation consistent in any field but at the end of the day, all it does is help the user and understand following things:-&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What is to happen?&lt;/li&gt;
&lt;li&gt;What did happen?&lt;/li&gt;
&lt;li&gt;How did it happen? and Conclusion for others to use.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Why Documentation?
&lt;/h2&gt;

&lt;p&gt;Since I am working in the programming sector, I’ll be explaining why we need it in coding using the above points. &lt;/p&gt;

&lt;h3&gt;
  
  
  What is to happen?
&lt;/h3&gt;

&lt;p&gt;The first point, ”What is to happen?” helps us understand the idea of what we actually need to do so that we can create logic to face that problem more easily. You may say I can visualize the code all on my own so there is no need to write it down that’s where I say, It’s okay if the logic you are developing is very simple but what if it’s not? What if the logic you are developing is very complicated and you get lost on the logic you were developing due to bugs? That’s where documentation on what is to happen is required. Even if you are developing a database, the database you just end up with might not be the best result. There are lots of benefits of doing documentation on coding what you are about to do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * To check if "n" is a prime number
 *
 * What I know?
 * 1) Prime number is the one which is no divisible by no other number but itself and 1
 * 2) I don't need to include 1 (Divides all numbers)
 * 3) I don't need to include n (Divides itself)
 *
 * Range should be from 2-n
 */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What did happen?
&lt;/h3&gt;

&lt;p&gt;When building logic, there might be an occurrence where you find a great idea that you didn’t find anywhere on the internet and you implement it. Since no one but you implemented it, others might have no idea how it works. And the thing about coding is no matter how clean code you write, It does get a lot more difficult to remember what you did to solve that problem later.&lt;/p&gt;

&lt;p&gt;Several developers may have problems in this section. In my case, I was trying to create a three-lane game, and I found a great way of making it work without using an addition. But when I was trying to put the finishing touches on it, I had no idea how everything was working. It took me another hour or so to go through everything to finally get what I actually did. &lt;/p&gt;

&lt;p&gt;So writing about what happened in coding helps you revisit the code and understand the genius idea you had not only for yourself but for other developers as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function primeNumber(n) {
    let isPrime = true;

    if (n % 2 === 0 &amp;amp;&amp;amp; n !== 2) {
        // All even numbers are not prime except 2
        return false;
    }

    for (let i = 2; i &amp;lt; n / 2; i++) {
        // We have dont n/2 since any number which is greater than n/2 while dividing will give result less than 1
        const reminder = n % i;

        if (!reminder) {
            isPrime = false;

            break; // Since we don't need to check for other numbers if it's not prime
        }
    }

        return isPrime;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How did it happen? and Conclusion for others to use.
&lt;/h3&gt;

&lt;p&gt;This is the point which most of the developers are most familiar with. Writing about a function or a class including what it does, what is returns, and what are the requirements for it to run. If someone is using JS, there is JSDocs and another programming language has a similar documentation standard which is used by almost all developers for the reusability of the code.&lt;/p&gt;

&lt;p&gt;While the other two parts are used for the purpose of understanding the code, this part is only written for the functional aspect. For example, you want to find a prime number and someone has created a function already to calculate the prime number, you don't usually need to know how they are calculating the prime number, you just want to know what they give as result and what they take in input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * The function checks if a given number is prime
 *
 * @param {number} n - The parameter "n" represents the number that we want to check if it is a prime number or
 * not.
 * @returns The function is not returning anything.
 */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to document a code?
&lt;/h2&gt;

&lt;p&gt;To document a code, the simplest way is to use the standard commenting such as JSDocs for JS. It's most widely used and even if a new developer opens the code they can understand it quite easily. &lt;/p&gt;

&lt;p&gt;The smallest way to document a code would be to use proper names for variables and functions which makes life way easier for refactor purposes or to change later down the line.&lt;/p&gt;

&lt;h2&gt;
  
  
  Not Always Possible
&lt;/h2&gt;

&lt;p&gt;Saying how documentation is required, we might be pushed to think that we need to include it everywhere, but as we developers know, it's always not the case. Tight deadlines, and managing multiple projects, are only a few of the problems one might face while on a project which might not make it possible for us to write documentation at every moment.&lt;/p&gt;

&lt;p&gt;Writing code in a particular architecture such as &lt;a href="https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html" rel="noopener noreferrer"&gt;Clean architecture&lt;/a&gt;, or &lt;a href="https://atomicdesign.bradfrost.com/chapter-2/" rel="noopener noreferrer"&gt;atomic structure pattern&lt;/a&gt; can also be a way for other developer to understand the code more easily.&lt;/p&gt;

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

&lt;p&gt;Documentation even if we don't use at all is there for easement of ourselves and/or other developers working together in the project. Adding the small line of comment indicating what happens when you run a function helps a long time for any other developer trying to work on that project and if you work on it after months then it will surely be ease for you as well.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>discuss</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Wireframing and HTML Structure: The Unsung Heroes of Frontend Development</title>
      <dc:creator>Raj Maharjan</dc:creator>
      <pubDate>Sat, 23 Sep 2023 06:40:42 +0000</pubDate>
      <link>https://dev.to/dubbyding/wireframing-and-html-structure-the-unsung-heroes-of-frontend-development-7f2</link>
      <guid>https://dev.to/dubbyding/wireframing-and-html-structure-the-unsung-heroes-of-frontend-development-7f2</guid>
      <description>&lt;p&gt;We have all been there, Everyone is saying how good the pay there is in IT so the first thing we look at is frontend development. We explore the internet, looking at every tutorial on YouTube, w3schools, and other platforms. They all show you the HTML tags and CSS properties. They are doing a good job getting us familiar with the concept of where to use specific tags and CSS properties. But the problem occurs when we try to duplicate a page on our own with the knowledge we gained from those videos. We could follow them word to word, line to line to create the webpage they were showing in their tutorial but when we do it ourselves it gets hard. Even if we use ‘flex’ and ‘grid’ to fix our design for the desktop, it becomes very hard when it comes to making the page responsive. The core parts which should be wireframing and HTML structure are the thing that almost all of the tutorials forget to mention.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Wireframing?
&lt;/h2&gt;

&lt;p&gt;Wireframing is something that usually no frontend developer is seen doing. Every task for building and creating the webpage seems so second nature that they just look at the design and start to implement it to create responsiveness in every device but when we are starting out, that second nature of the developer seems like magic of a kind. They write the code and it works but you try to do the same but it doesn’t work. The design that you just coded in HTML and CSS is not showing as in the design. What wireframing does is help you visualize even more in detail what every part goes on the webpage. If you are using libraries or frameworks, you can treat them like components that help you visualize the design and how to implement it more clearly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Wireframing?
&lt;/h2&gt;

&lt;p&gt;Wireframing should be taken as a tool that can help improve our productivity and like any tool to use it requires practice. I have tried and made a few myself and later down the road, I felt that the wireframe that I designed for the page was very inadequate and of very low quality. It is an iterative process where we create a wireframe and try to implement it, feel like the wireframe was not good enough to get a proper result, try what can be improved in code, and try to implement that in the wireframe again. Then try to create a better version of the wireframe and the circle continues for the case for learning which helps us visualize and structure our HTML document properly.&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%2Fwua5pvwh86134vzkzygg.jpg" 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%2Fwua5pvwh86134vzkzygg.jpg" alt="Sample Wireframe of GitHub Profile Page" width="800" height="1158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is HTML Structuring?
&lt;/h2&gt;

&lt;p&gt;Similar to wireframing, HTML structuring is something an experienced frontend developer just does without even breaking a sweat but becomes a big factor when making a site responsive. Normally whenever there is a problem in the responsiveness of the site it’s due to the HTML not being structured properly.&lt;/p&gt;

&lt;p&gt;So what is this HTML Structuring? It is referred to as the proper way of containerizing your application's structure using proper semantics or div tags in the proper situation. This not only helps with the responsiveness of our webpage but also helps with the SEO of our site to be deployed which is an important factor if you want your site to show up in search engines like Google. &lt;/p&gt;

&lt;h2&gt;
  
  
  Connection of Wireframe with HTML Structuring
&lt;/h2&gt;

&lt;p&gt;Creating a proper wireframe helps us plan to structure our HTML properly. Wireframe helps us visualize the tags before writing them into an IDE, such as Visual Studio Code, which helps you smooth out our workflow for senior developers and makes it easier for starters on frontend to create a proper clone of the website on their own.&lt;/p&gt;

&lt;p&gt;For newcomers, I recommend building a clone of any site you are building using Float. Float seems simple, but if any of the HTML structures are off, the design doesn’t clone itself properly. I also recommend not using ChatGPT for learning purposes for this particular exercise. There is a quote by Monica of F.R.I.E.N.D.S that I'd like to share with a twist of programming, "Welcome to the real world. It sucks. You’re gonna love it." &lt;/p&gt;

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

&lt;p&gt;Proper wireframes and proper HTML structure actually go hand in hand. Proper wireframes can lead to proper HTML for smoother workflow and learning while proper HTML structure helps to make the wireframes better as well.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>frontend</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
