<?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: Sohana Akbar</title>
    <description>The latest articles on Forem by Sohana Akbar (@sohanaakbar7).</description>
    <link>https://forem.com/sohanaakbar7</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%2F3878706%2Fb026acb6-e832-44ba-9999-2c0e44f18218.jpg</url>
      <title>Forem: Sohana Akbar</title>
      <link>https://forem.com/sohanaakbar7</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sohanaakbar7"/>
    <language>en</language>
    <item>
      <title>Imposter syndrome at 18 — it's real</title>
      <dc:creator>Sohana Akbar</dc:creator>
      <pubDate>Sat, 09 May 2026 14:27:34 +0000</pubDate>
      <link>https://forem.com/sohanaakbar7/imposter-syndrome-at-18-its-real-570h</link>
      <guid>https://forem.com/sohanaakbar7/imposter-syndrome-at-18-its-real-570h</guid>
      <description>&lt;h1&gt;
  
  
  Imposter syndrome at 18 — it's real
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; You're not a fraud. You're just starting. There's a difference.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Voice In My Head
&lt;/h2&gt;

&lt;p&gt;I'm 18. I know frontend development. I know DevOps.&lt;/p&gt;

&lt;p&gt;And yet, every single day, my brain tells me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"You don't actually know anything."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Someone else is better. Someone younger. Someone who actually deserves to be here."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"They're going to find out you're faking it."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That voice? That's imposter syndrome.&lt;/p&gt;

&lt;p&gt;And at 18? It hits different.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why It's Worse When You're Young
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Age&lt;/th&gt;
&lt;th&gt;What People Think&lt;/th&gt;
&lt;th&gt;What You Feel&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;25+&lt;/td&gt;
&lt;td&gt;"They have experience"&lt;/td&gt;
&lt;td&gt;"I belong here"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;"They're just a kid"&lt;/td&gt;
&lt;td&gt;"Everyone is better than me"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;At 18, you don't have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A degree to prove yourself&lt;/li&gt;
&lt;li&gt;Years of experience to point to&lt;/li&gt;
&lt;li&gt;A network of seniors who "get it"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You just have... you. And that little voice.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Comparison Trap
&lt;/h2&gt;

&lt;p&gt;I open LinkedIn → someone my age is working at Google.&lt;/p&gt;

&lt;p&gt;I open Twitter → a 16-year-old just launched a SaaS making $10k/month.&lt;/p&gt;

&lt;p&gt;I open GitHub → someone's repo has 5k stars. Mine has 3.&lt;/p&gt;

&lt;p&gt;And suddenly, my brain says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"You're behind. You're not enough. You'll never catch up."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Sound familiar?&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What Nobody Tells You
&lt;/h2&gt;

&lt;p&gt;The people you're comparing yourself to?&lt;/p&gt;

&lt;p&gt;They feel the same way.&lt;/p&gt;

&lt;p&gt;That 16-year-old with $10k/month? They probably think they're lucky, not skilled.&lt;/p&gt;

&lt;p&gt;That Google intern? They're terrified someone will find out they don't know how to merge a PR.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Imposter syndrome doesn't care about your age or success.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It just cares that you're human.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Reframe That Saved Me
&lt;/h2&gt;

&lt;p&gt;I used to think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I don't know enough."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now I think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I don't know enough &lt;em&gt;yet&lt;/em&gt;."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One word. "Yet."&lt;/p&gt;

&lt;p&gt;It changes everything.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I don't know Kubernetes... &lt;em&gt;yet&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;I haven't landed a client... &lt;em&gt;yet&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;I'm not making money... &lt;em&gt;yet&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;"Yet" gives you permission to be a beginner.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5 Things That Actually Help
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Save Your Wins
&lt;/h3&gt;

&lt;p&gt;Create a folder called "wins" on your phone.&lt;/p&gt;

&lt;p&gt;Every time you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fix a bug&lt;/li&gt;
&lt;li&gt;Deploy something&lt;/li&gt;
&lt;li&gt;Help someone&lt;/li&gt;
&lt;li&gt;Learn something new&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Screenshot it. Save it.&lt;/p&gt;

&lt;p&gt;On bad days, open that folder.&lt;/p&gt;

&lt;p&gt;You'll realize: &lt;em&gt;"Oh. I actually did stuff."&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Talk About It
&lt;/h3&gt;

&lt;p&gt;Say it out loud:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I feel like I don't know what I'm doing."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To a friend. To Twitter. To a rubber duck.&lt;/p&gt;

&lt;p&gt;The moment you say it, it loses power.&lt;/p&gt;

&lt;p&gt;Silence makes it grow. Speaking shrinks it.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Find Your People
&lt;/h3&gt;

&lt;p&gt;Follow other young devs on X/LinkedIn.&lt;/p&gt;

&lt;p&gt;Comment on their posts. DM them.&lt;/p&gt;

&lt;p&gt;When you see someone else struggling, you realize:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Oh. It's not just me."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Community &amp;gt; Competition.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Stop Comparing Inputs to Outputs
&lt;/h3&gt;

&lt;p&gt;You see someone's highlight reel.&lt;/p&gt;

&lt;p&gt;You compare it to your behind-the-scenes.&lt;/p&gt;

&lt;p&gt;That's not fair to you.&lt;/p&gt;

&lt;p&gt;That person also:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cried over a bug&lt;/li&gt;
&lt;li&gt;Got rejected&lt;/li&gt;
&lt;li&gt;Felt like giving up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You just didn't see it.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Do It Scared
&lt;/h3&gt;

&lt;p&gt;Here's the secret:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Everyone feels like a fraud.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The difference is: some people do it anyway.&lt;/p&gt;

&lt;p&gt;Deploy that app even if it's ugly.&lt;br&gt;
Write that article even if no one reads it.&lt;br&gt;
Apply for that job even if you think you're underqualified.&lt;/p&gt;

&lt;p&gt;Do it scared. Do it messy. Just do it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Tell Myself Now
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"You're 18. You're supposed to not know things. That's literally the point of being 18."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You're not supposed to have it figured out.&lt;/p&gt;

&lt;p&gt;You're supposed to be learning, failing, trying, breaking, fixing, growing.&lt;/p&gt;

&lt;p&gt;That's not imposter syndrome.&lt;/p&gt;

&lt;p&gt;That's being a beginner.&lt;/p&gt;

&lt;p&gt;And being a beginner is not a crime. It's a stage.&lt;/p&gt;




&lt;h2&gt;
  
  
  Your Turn
&lt;/h2&gt;

&lt;p&gt;If you're reading this and you feel like a fraud:&lt;/p&gt;

&lt;p&gt;You're not.&lt;/p&gt;

&lt;p&gt;You're just human. In progress. Still cooking.&lt;/p&gt;

&lt;p&gt;And that's perfectly okay.&lt;/p&gt;

&lt;p&gt;Drop a ❤️ if this hit home. Or reply with your own imposter syndrome story.&lt;/p&gt;

&lt;p&gt;Let's be real with each other.&lt;/p&gt;

</description>
      <category>mentalhealth</category>
      <category>career</category>
      <category>productivity</category>
      <category>beginners</category>
    </item>
    <item>
      <title>"I Failed My First AWS Certification Attempt" – Here’s What I Learned (And Why You Shouldn’t Panic)</title>
      <dc:creator>Sohana Akbar</dc:creator>
      <pubDate>Fri, 08 May 2026 13:47:16 +0000</pubDate>
      <link>https://forem.com/sohanaakbar7/i-failed-my-first-aws-certification-attempt-heres-what-i-learned-and-why-you-shouldnt-panic-3388</link>
      <guid>https://forem.com/sohanaakbar7/i-failed-my-first-aws-certification-attempt-heres-what-i-learned-and-why-you-shouldnt-panic-3388</guid>
      <description>&lt;p&gt;Failure isn’t the end. It’s just a very expensive practice exam.&lt;/p&gt;

&lt;p&gt;Let me set the scene.&lt;/p&gt;

&lt;p&gt;I’d spent weeks watching video courses, highlighting cheat sheets, and answering practice questions. I walked into that exam center (yes, online proctored, but emotionally, I was walking in) feeling ready.&lt;/p&gt;

&lt;p&gt;Three hours later, I saw the screen: FAIL.&lt;/p&gt;

&lt;p&gt;No cute confetti. No “close enough.” Just a cold, numeric score below passing.&lt;/p&gt;

&lt;p&gt;I felt embarrassed, frustrated, and honestly – a little stupid.&lt;/p&gt;

&lt;p&gt;But here’s what I’ve realized three months, one retake, and one certification later: failing was the best thing that could’ve happened to me.&lt;/p&gt;

&lt;p&gt;Why I Really Failed&lt;br&gt;
Let me save you the trouble of overthinking:&lt;/p&gt;

&lt;p&gt;I memorized, not understood. I knew S3 bucket policies by heart but couldn’t explain why one fails over another.&lt;/p&gt;

&lt;p&gt;Practice exams ≠ real exam. The real test twists scenarios, mixes services, and loves those “choose TWO answers” questions.&lt;/p&gt;

&lt;p&gt;Time management? What time management? I spent 10 minutes on one VPC question and panicked through the rest.&lt;/p&gt;

&lt;p&gt;You might relate. And that’s okay.&lt;/p&gt;

&lt;p&gt;What I Did Differently the Second Time&lt;br&gt;
After licking my wounds for a few days, I got practical.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I read the official exam guide (actually read it)&lt;br&gt;
Weirdly helpful. It tells you exactly which domains are weighted heavily. Stop guessing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hands-on &amp;gt; passive learning&lt;br&gt;
I built tiny things. A static site on S3 + CloudFront. A serverless API with Lambda + API Gateway. Broke them. Fixed them. That stuck.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reviewed every wrong answer (even the ones I guessed right)&lt;br&gt;
If you can’t explain why an option is wrong, you don’t know the topic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Used TutorialsDojo &amp;amp; AWS Skill Builder&lt;br&gt;
These were the closest to the real exam format. Worth every penny.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Hardest Part? Your Ego&lt;br&gt;
Nobody likes to fail. Especially when you’ve told your manager, posted on LinkedIn about “studying for AWS cert,” or spent your own money on exam fees.&lt;/p&gt;

&lt;p&gt;But here’s the truth: no one in tech cares if you failed a cert exam.&lt;/p&gt;

&lt;p&gt;They care if you can solve problems, learn from mistakes, and try again.&lt;/p&gt;

&lt;p&gt;When I retook the exam (and passed), nothing changed dramatically. No promotion fairy showed up. But I changed. I became better at AWS, better at debugging, and less afraid of being wrong.&lt;/p&gt;

&lt;p&gt;So You Failed. Now What?&lt;br&gt;
Download your score report – See which domains you bombed. Focus there.&lt;/p&gt;

&lt;p&gt;Take 2-3 days off – No AWS. No studying. Clear your head.&lt;/p&gt;

&lt;p&gt;Book your retake – Having a date makes the comeback real.&lt;/p&gt;

&lt;p&gt;Change your study method – If videos didn’t work, try hands-on labs. If practice exams failed you, try a different vendor.&lt;/p&gt;

&lt;p&gt;One Last Thing&lt;br&gt;
That failure score report is still in my email. I didn’t delete it.&lt;/p&gt;

&lt;p&gt;Every few months, I scroll past it and smile. Because that failed attempt taught me more than any “pass” ever could.&lt;/p&gt;

&lt;p&gt;You didn’t fail. You just found one way that didn’t work.&lt;/p&gt;

&lt;p&gt;Now go book that retake. You’ve got this. 💪&lt;/p&gt;

&lt;p&gt;Did you fail your first AWS cert too? Drop a 🙋 in the comments – let’s normalize learning in public.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>NGINX for beginners — what even is a reverse proxy?</title>
      <dc:creator>Sohana Akbar</dc:creator>
      <pubDate>Thu, 07 May 2026 13:25:39 +0000</pubDate>
      <link>https://forem.com/sohanaakbar7/nginx-for-beginners-what-even-is-a-reverse-proxy-5ai0</link>
      <guid>https://forem.com/sohanaakbar7/nginx-for-beginners-what-even-is-a-reverse-proxy-5ai0</guid>
      <description>&lt;p&gt;If you are just starting your web development journey, you’ve probably heard the name NGINX (pronounced "Engine-X") thrown around. Maybe you followed a tutorial to deploy a React app and you had to copy-paste some mysterious location / blocks into a config file.&lt;/p&gt;

&lt;p&gt;But here is the big question that stops everyone cold: What even is a reverse proxy?&lt;/p&gt;

&lt;p&gt;Let’s ditch the jargon. By the end of this 5-minute read, you’ll understand exactly what NGINX does, why "proxy" isn't a scary word, and why the internet practically runs on this software.&lt;/p&gt;

&lt;p&gt;First, the "Normal" Proxy (The One you already know)&lt;br&gt;
To understand a reverse proxy, we need to look at a forward proxy first.&lt;/p&gt;

&lt;p&gt;Imagine you are at work or school. You want to watch a video game stream, but the office Wi-Fi blocks it.&lt;/p&gt;

&lt;p&gt;The Setup:&lt;/p&gt;

&lt;p&gt;You (The Client)&lt;/p&gt;

&lt;p&gt;The Office Wi-Fi (The Proxy)&lt;/p&gt;

&lt;p&gt;The Game Stream (The Server)&lt;/p&gt;

&lt;p&gt;Instead of connecting directly to the game server, you ask the proxy to do it for you. The proxy hides your identity and bypasses the block.&lt;/p&gt;

&lt;p&gt;Forward Proxy Job: "Hides the client (you) from the server."&lt;/p&gt;

&lt;p&gt;So, What is a Reverse Proxy?&lt;br&gt;
Now, flip that diagram upside down.&lt;/p&gt;

&lt;p&gt;You are chilling at home, and you want to visit google.com. You type it into your browser. You don't actually talk to the main Google computers; you talk to a reverse proxy.&lt;/p&gt;

&lt;p&gt;The Setup:&lt;/p&gt;

&lt;p&gt;You (The Client)&lt;/p&gt;

&lt;p&gt;The NGINX Server (The Reverse Proxy)&lt;/p&gt;

&lt;p&gt;The App/Coding (The Internal Server)&lt;/p&gt;

&lt;p&gt;Reverse Proxy Job: "Hides the server from the client (you)."&lt;/p&gt;

&lt;p&gt;You think you are talking to the main computer, but you are actually talking to NGINX, which then politely talks to the main computer for you.&lt;/p&gt;

&lt;p&gt;Why Should You Care? (The 3 Superpowers of NGINX)&lt;br&gt;
If all it does is "hide the server," why is NGINX used by Netflix, Airbnb, and Dropbox? Because hiding the server gives you three magical powers.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Load Balancing (The Traffic Cop)
Let’s say your Node.js app goes viral. One server can't handle 1 million users at once. You spin up 3 identical servers.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without NGINX: All 1 million users crash into Server #1. Chaos.&lt;/p&gt;

&lt;p&gt;With NGINX: NGINX sits in front and says, "User 1, go to Server A. User 2, go to Server B. User 3, go to Server C."&lt;/p&gt;

&lt;p&gt;NGINX spreads the work so no single server has a meltdown.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SSL Termination (The Security Guard)
HTTPS (the padlock in your browser) is complicated to set up on every single app server.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Without NGINX: You have to configure SSL certificates on your Node app, your Python app, and your Go app. Nightmare.&lt;/p&gt;

&lt;p&gt;With NGINX: You configure the certificate once on NGINX. NGINX catches the encrypted traffic, decrypts it, and sends the safe, simple HTTP traffic to your internal apps.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Serving Static Files (The Speed Demon)
Here is the secret that blows most beginners' minds: You should not use your fancy backend code (Python/Node/Ruby) to serve images, CSS, or HTML.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Backend languages are slow at serving files because they have to "think." NGINX is written in C and optimized for this exact job.&lt;/p&gt;

&lt;p&gt;nginx&lt;/p&gt;

&lt;h1&gt;
  
  
  A typical NGINX config for a React app
&lt;/h1&gt;

&lt;p&gt;server {&lt;br&gt;
    listen 80;&lt;br&gt;
    server_name mywebsite.com;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;location / {
    # Don't touch the React files!
    root /var/www/html;
    try_files $uri /index.html;
}

location /api {
    # Wait... this is a reverse proxy!
    # If the URL has /api, send it to my backend server.
    proxy_pass http://localhost:3000;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
The "Aha!" Moment&lt;br&gt;
Look at the config above again. See that /api block?&lt;/p&gt;

&lt;p&gt;On the same domain (mywebsite.com), NGINX is doing two things:&lt;/p&gt;

&lt;p&gt;Serving your HTML/CSS directly (fast).&lt;/p&gt;

&lt;p&gt;Proxying your API requests to your backend (hidden).&lt;/p&gt;

&lt;p&gt;If your browser visits mywebsite.com/api/users, NGINX doesn't say "I don't know that route." It says, "Hold on, I know a guy," and forwards the request to localhost:3000/users.&lt;/p&gt;

&lt;p&gt;The user (the browser) has no idea your backend is running on port 3000. The server (Node.js) has no idea if the user is on a phone or a laptop. They are completely hidden from each other.&lt;/p&gt;

&lt;p&gt;How to Prove This to Yourself (5 minutes)&lt;br&gt;
You don't need to deploy to the cloud to see this work. Do this on your laptop:&lt;/p&gt;

&lt;p&gt;Install NGINX (use Homebrew on Mac, apt on Linux, or Docker).&lt;/p&gt;

&lt;p&gt;Start a simple Python server: python -m http.server 8000&lt;/p&gt;

&lt;p&gt;Add this to your NGINX config:&lt;/p&gt;

&lt;p&gt;nginx&lt;br&gt;
server {&lt;br&gt;
    listen 8080;&lt;br&gt;
    location / {&lt;br&gt;
        proxy_pass &lt;a href="http://localhost:8000" rel="noopener noreferrer"&gt;http://localhost:8000&lt;/a&gt;;&lt;br&gt;
    }&lt;br&gt;
}&lt;br&gt;
Restart NGINX and visit localhost:8080. You are looking at your Python server via the NGINX proxy.&lt;/p&gt;

&lt;p&gt;The Bottom Line&lt;br&gt;
Stop thinking of NGINX as a scary server "thing." Think of it as Reception Desk for the Internet.&lt;/p&gt;

&lt;p&gt;A visitor arrives (HTTP Request).&lt;/p&gt;

&lt;p&gt;NGINX asks: "Do you want a photo? (I'll handle it). Do you want to log in? (I'll call the backend). Is this person annoying? (I'll block them)."&lt;/p&gt;

&lt;p&gt;The visitor never sees the chaos happening in the back office.&lt;/p&gt;

&lt;p&gt;That is a reverse proxy. That is NGINX.&lt;/p&gt;

&lt;p&gt;Once you understand that, the entire world of DevOps, microservices, and cloud hosting suddenly makes a lot more sense.&lt;/p&gt;

&lt;p&gt;Found this helpful? Let me know in the comments if you want a Part 2 on "The 5 most common NGINX config mistakes beginners make."&lt;/p&gt;

</description>
      <category>nginx</category>
      <category>beginners</category>
      <category>networking</category>
    </item>
    <item>
      <title>My React Folder Structure (Opinionated but Works)</title>
      <dc:creator>Sohana Akbar</dc:creator>
      <pubDate>Wed, 06 May 2026 15:59:28 +0000</pubDate>
      <link>https://forem.com/sohanaakbar7/my-react-folder-structure-opinionated-but-works-2m66</link>
      <guid>https://forem.com/sohanaakbar7/my-react-folder-structure-opinionated-but-works-2m66</guid>
      <description>&lt;p&gt;TL;DR: Stop throwing everything into components/. After 6 production apps and 3 burned-out refactors, I landed on a feature-based, domain-driven structure that scales from 1 to 100 components.&lt;/p&gt;

&lt;p&gt;I have tried every structure: grouped by type, grouped by route, atomic design, and even "just throw it in src." This is the one that finally made me stop crying during code reviews.&lt;/p&gt;

&lt;p&gt;The Golden Rule: Co-location of Concern&lt;br&gt;
"Files that change together, live together."&lt;/p&gt;

&lt;p&gt;If you are editing UserProfile.tsx and you have to jump to 4 different folders (components/, hooks/, types/, services/), your structure is broken.&lt;/p&gt;

&lt;p&gt;Here is the tree view of my happy place:&lt;/p&gt;

&lt;p&gt;text&lt;br&gt;
src/&lt;br&gt;
├── features/               # The 🐐 (core domain logic)&lt;br&gt;
│   ├── auth/               # Single feature&lt;br&gt;
│   │   ├── components/     # ONLY used by this feature&lt;br&gt;
│   │   ├── hooks/          # Feature-specific hooks&lt;br&gt;
│   │   ├── types/          # TS interfaces/domain types&lt;br&gt;
│   │   ├── api/            # API calls for this feature&lt;br&gt;
│   │   └── index.ts        # Public API for the feature&lt;br&gt;
│   ├── dashboard/&lt;br&gt;
│   └── settings/&lt;br&gt;
│&lt;br&gt;
├── shared/                 # Reusable, but NOT business logic&lt;br&gt;
│   ├── ui/                 # Dumb components (Button, Modal, Card)&lt;br&gt;
│   │   ├── Button/&lt;br&gt;
│   │   ├── Modal/&lt;br&gt;
│   │   └── index.ts&lt;br&gt;
│   ├── lib/                # Utils, formatters, constants&lt;br&gt;
│   ├── hooks/              # Generic hooks (useLocalStorage, useDebounce)&lt;br&gt;
│   └── api/                # Axios/fetch instance, interceptors&lt;br&gt;
│&lt;br&gt;
├── app/                    # Next.js/React Router setup&lt;br&gt;
│   ├── routes/             # Route configuration&lt;br&gt;
│   └── providers/          # Context providers (Theme, QueryClient)&lt;br&gt;
│&lt;br&gt;
├── layouts/                # AuthLayout, DashboardLayout&lt;br&gt;
│&lt;br&gt;
└── main.tsx                # Entry point&lt;br&gt;
Deep Dive: The features/ Folder (Where the magic happens)&lt;br&gt;
Each feature is a mini-app. It owns everything it needs. No imports jumping across the galaxy.&lt;/p&gt;

&lt;p&gt;Example: features/auth/&lt;br&gt;
typescript&lt;br&gt;
// features/auth/types/index.ts&lt;br&gt;
export interface User {&lt;br&gt;
  id: string;&lt;br&gt;
  email: string;&lt;br&gt;
  role: 'admin' | 'user';&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;// features/auth/api/authApi.ts&lt;br&gt;
import { apiClient } from '@/shared/api';&lt;br&gt;
import type { User } from '../types';&lt;/p&gt;

&lt;p&gt;export const authApi = {&lt;br&gt;
  login: (email: string, password: string) =&amp;gt; &lt;br&gt;
    apiClient.post('/auth/login', { email, password }),&lt;br&gt;
  logout: () =&amp;gt; apiClient.post('/auth/logout')&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;// features/auth/hooks/useLogin.ts&lt;br&gt;
import { useMutation } from '@tanstack/react-query';&lt;br&gt;
import { authApi } from '../api/authApi';&lt;/p&gt;

&lt;p&gt;export const useLogin = () =&amp;gt; {&lt;br&gt;
  return useMutation({&lt;br&gt;
    mutationFn: authApi.login,&lt;br&gt;
    onSuccess: (user) =&amp;gt; {&lt;br&gt;
      // Handle success locally inside the feature&lt;br&gt;
    }&lt;br&gt;
  });&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;// features/auth/components/LoginForm.tsx&lt;br&gt;
import { useLogin } from '../hooks/useLogin';&lt;br&gt;
import { Button } from '@/shared/ui/Button'; // Only shared UI allowed&lt;/p&gt;

&lt;p&gt;export const LoginForm = () =&amp;gt; {&lt;br&gt;
  const { mutate } = useLogin();&lt;br&gt;
  return  mutate(...)}&amp;gt;Login;&lt;br&gt;
};&lt;/p&gt;

&lt;p&gt;// features/auth/index.ts (Public API)&lt;br&gt;
export { LoginForm } from './components/LoginForm';&lt;br&gt;
export { useLogin } from './hooks/useLogin';&lt;br&gt;
export type { User } from './types';&lt;br&gt;
Rule: No cross-imports between features ❌&lt;br&gt;
typescript&lt;br&gt;
// BAD: Dashboard importing directly from auth's internal folder&lt;br&gt;
import { useLogin } from '@/features/auth/hooks/useLogin';&lt;/p&gt;

&lt;p&gt;// GOOD: Use the feature's public index.ts&lt;br&gt;
import { useLogin } from '@/features/auth';&lt;br&gt;
Why? Later, you can delete the auth/ folder entirely without breaking dashboard/ if you do it right.&lt;/p&gt;

&lt;p&gt;The shared/ Folder (The innocent box of Legos)&lt;br&gt;
This is where pure, reusable, business-logic-free code lives.&lt;/p&gt;

&lt;p&gt;Subfolder   Contents    Example&lt;br&gt;
ui/ Presentational components   Button, Input, Card, Modal (No API calls!)&lt;br&gt;
hooks/  Generic React hooks useLocalStorage, useMediaQuery, useCopyToClipboard&lt;br&gt;
lib/    Pure functions  formatDate, cn() (clsx/tailwind-merge), generateId&lt;br&gt;
api/    Configured HTTP client  Axios instance with baseURL, interceptors, auth headers&lt;br&gt;
The shared/ui/ pattern (Bonus)&lt;br&gt;
I use a barrel export for UI components:&lt;/p&gt;

&lt;p&gt;typescript&lt;br&gt;
// shared/ui/Button/Button.tsx&lt;br&gt;
export const Button = (props) =&amp;gt; { ... };&lt;/p&gt;

&lt;p&gt;// shared/ui/Button/index.ts&lt;br&gt;
export * from './Button';&lt;/p&gt;

&lt;p&gt;// shared/ui/index.ts&lt;br&gt;
export { Button } from './Button';&lt;br&gt;
export { Modal } from './Modal';&lt;br&gt;
Then in any feature or layout:&lt;/p&gt;

&lt;p&gt;typescript&lt;br&gt;
import { Button, Modal } from '@/shared/ui';&lt;br&gt;
Why This Works (The Opinionated Part)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It destroys "God Components"&lt;br&gt;
When everything lives in components/, you eventually create UserDashboardFormWithSidebarAndHeaderAndFooter.tsx. In feature folders, you are forced to split.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deleting features is safe&lt;br&gt;
Marketing wants a temporary landing page feature? Clone features/landing/ into it. Then delete it. No orphaned hooks, no broken imports.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Types are treated as first-class citizens&lt;br&gt;
No more types.ts at the root with 3,000 lines. Each feature defines its own domain types. If two features need the same type, it belongs in shared/types/.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It works with every meta-framework&lt;br&gt;
Next.js (App Router): features/ sit next to app/&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Vite + React Router: features/ import shared/&lt;/p&gt;

&lt;p&gt;Remix: Same thing.&lt;/p&gt;

&lt;p&gt;Real-World Exception (Because perfect doesn't exist)&lt;br&gt;
Exception #1: Global state (Zustand, Redux, Jotai)&lt;/p&gt;

&lt;p&gt;Store global slices in stores/ inside app/, not inside features/.&lt;/p&gt;

&lt;p&gt;Only put feature-scoped state inside the feature folder.&lt;/p&gt;

&lt;p&gt;Exception #2: Shared types across 3+ features&lt;/p&gt;

&lt;p&gt;Move to shared/types/. Example: ApiResponse.&lt;/p&gt;

&lt;p&gt;The Migration Path (If you are converting an existing app)&lt;br&gt;
Create shared/ui/ and move Button, Card, Input there. (1 hour)&lt;/p&gt;

&lt;p&gt;Pick ONE feature (e.g., auth). Create the folder structure. Move its components, hooks, and API calls inside. (2 hours)&lt;/p&gt;

&lt;p&gt;Update imports for that one feature. Use your IDE's refactor tools.&lt;/p&gt;

&lt;p&gt;Repeat for the second feature. The third one will take 10 minutes.&lt;/p&gt;

&lt;p&gt;Delete the old components/ folder when it's empty. Full send.&lt;/p&gt;

&lt;p&gt;The Verdict&lt;br&gt;
Is this the only way? No.&lt;br&gt;
Does it work for a 50-component side project? Overkill.&lt;br&gt;
Does it work for a 500-component enterprise app with 6 developers? Yes. Every. Single. Time.&lt;/p&gt;

&lt;p&gt;If you take one thing away: Don't organize by file type. Organize by feature.&lt;/p&gt;

&lt;p&gt;What does your React folder structure look like? Did I miss your pet pattern? Let me know in the comments — but be nice, my structure is "opinionated but works" for a reason. 😅&lt;/p&gt;

&lt;p&gt;P.S. If you want the TypeScript paths config to make @/ work:&lt;/p&gt;

&lt;p&gt;json&lt;br&gt;
// tsconfig.json&lt;br&gt;
{&lt;br&gt;
  "compilerOptions": {&lt;br&gt;
    "paths": {&lt;br&gt;
      "@/&lt;em&gt;": ["./src/&lt;/em&gt;"]&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>frontend</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Environment Variables Explained (with .env file)</title>
      <dc:creator>Sohana Akbar</dc:creator>
      <pubDate>Tue, 05 May 2026 12:26:54 +0000</pubDate>
      <link>https://forem.com/sohanaakbar7/environment-variables-explained-with-env-file-3n5k</link>
      <guid>https://forem.com/sohanaakbar7/environment-variables-explained-with-env-file-3n5k</guid>
      <description>&lt;p&gt;Ever hardcoded an API key in your code? We've all been there. Then came the panic commit removing it right after. Let me show you the right way.&lt;/p&gt;

&lt;p&gt;What are environment variables?&lt;br&gt;
Environment variables are dynamic key-value pairs stored outside your application code. They live in the shell session or system environment, making them perfect for configuration that changes between environments.&lt;/p&gt;

&lt;p&gt;Think of them as settings you can change without touching your codebase.&lt;/p&gt;

&lt;p&gt;Why use them?&lt;br&gt;
Security - Keep secrets out of version control&lt;/p&gt;

&lt;p&gt;Portability - Same code, different configs (dev/staging/prod)&lt;/p&gt;

&lt;p&gt;Convenience - No more config files inside your repo&lt;/p&gt;

&lt;p&gt;The .env file&lt;br&gt;
A .env file is a plain text file in your project root that lists environment variables:&lt;/p&gt;

&lt;p&gt;bash&lt;/p&gt;

&lt;h1&gt;
  
  
  .env
&lt;/h1&gt;

&lt;p&gt;PORT=3000&lt;br&gt;
DATABASE_URL=postgresql://localhost:myapp&lt;br&gt;
API_KEY=abc123secret&lt;br&gt;
How to use it&lt;br&gt;
Most programming languages have packages to load .env files:&lt;/p&gt;

&lt;p&gt;Node.js (using dotenv):&lt;/p&gt;

&lt;p&gt;javascript&lt;br&gt;
require('dotenv').config()&lt;/p&gt;

&lt;p&gt;const port = process.env.PORT&lt;br&gt;
const dbUrl = process.env.DATABASE_URL&lt;br&gt;
Python (using python-dotenv):&lt;/p&gt;

&lt;p&gt;python&lt;br&gt;
from dotenv import load_dotenv&lt;br&gt;
import os&lt;/p&gt;

&lt;p&gt;load_dotenv()&lt;br&gt;
port = os.getenv('PORT')&lt;br&gt;
Go (using godotenv):&lt;/p&gt;

&lt;p&gt;go&lt;br&gt;
import "github.com/joho/godotenv"&lt;/p&gt;

&lt;p&gt;godotenv.Load()&lt;br&gt;
port := os.Getenv("PORT")&lt;br&gt;
Golden rules&lt;br&gt;
Never commit .env - Add it to .gitignore&lt;/p&gt;

&lt;p&gt;Create .env.example - Show required variables without secrets:&lt;/p&gt;

&lt;p&gt;text&lt;br&gt;
PORT=3000&lt;br&gt;
DATABASE_URL=&lt;br&gt;
API_KEY=your_key_here&lt;br&gt;
Use different values per environment - Local DB for dev, production DB for prod&lt;/p&gt;

&lt;p&gt;Production caveat&lt;br&gt;
In production, avoid .env files. Use your platform's native environment configuration:&lt;/p&gt;

&lt;p&gt;bash&lt;/p&gt;

&lt;h1&gt;
  
  
  Heroku / Railway / Render
&lt;/h1&gt;

&lt;p&gt;heroku config:set API_KEY=prod_secret_123&lt;/p&gt;

&lt;h1&gt;
  
  
  Docker
&lt;/h1&gt;

&lt;p&gt;docker run -e API_KEY=prod_secret_123 myapp&lt;br&gt;
Bottom line&lt;br&gt;
Environment variables separate what your app does from where it runs. Use them. Your future self (and teammates) will thank you.&lt;/p&gt;

&lt;p&gt;What's your go-to method for managing secrets across teams? Share below! 👇&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Basic Linux Commands Every Dev Should Know</title>
      <dc:creator>Sohana Akbar</dc:creator>
      <pubDate>Sun, 03 May 2026 14:27:59 +0000</pubDate>
      <link>https://forem.com/sohanaakbar7/basic-linux-commands-every-dev-should-know-1ej8</link>
      <guid>https://forem.com/sohanaakbar7/basic-linux-commands-every-dev-should-know-1ej8</guid>
      <description>&lt;p&gt;You don’t need to be a sysadmin to work comfortably in Linux. But as a developer, knowing the right 20% of commands will save you hours of clicking and debugging.&lt;/p&gt;

&lt;p&gt;Let’s cut the fluff. Here are the essential Linux commands I use daily.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Navigation &amp;amp; Inspection&lt;br&gt;
bash&lt;br&gt;
pwd                   # Where am I?&lt;br&gt;
ls -la                # List all files (including hidden) with details&lt;br&gt;
cd project/           # Move into directory&lt;br&gt;
cd ..                 # Go back one level&lt;br&gt;
cd ~                  # Go home&lt;br&gt;
Dev tip: Use ls -la | grep keyword to filter files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;File Operations (You’ll use these constantly)&lt;br&gt;
bash&lt;br&gt;
touch index.js        # Create empty file&lt;br&gt;
cat file.txt          # Print entire file to terminal&lt;br&gt;
head -20 app.log      # First 20 lines of log&lt;br&gt;
tail -f app.log       # Follow live log output (critical for debugging)&lt;br&gt;
cp -r src/ backup/    # Copy folder recursively&lt;br&gt;
mv oldname.js newname.js  # Rename or move&lt;br&gt;
rm file.txt           # Delete file (careful!)&lt;br&gt;
rm -rf node_modules/  # Delete folder (double careful!)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Process Management&lt;br&gt;
bash&lt;br&gt;
ps aux                # List all running processes&lt;br&gt;
ps aux | grep node    # Find Node processes&lt;br&gt;
kill -9 1234          # Force kill process with PID 1234&lt;br&gt;
kill -15 1234         # Graceful termination&lt;br&gt;
top                   # Live system monitor (press q to exit)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Permissions (Deployers &amp;amp; DevOps)&lt;br&gt;
bash&lt;br&gt;
chmod +x script.sh    # Make script executable&lt;br&gt;
chmod 644 file.txt    # rw-r--r-- (owner read/write, others read)&lt;br&gt;
sudo command          # Run as superuser (careful!)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finding Stuff&lt;br&gt;
bash&lt;br&gt;
grep "error" app.log              # Search inside file&lt;br&gt;
grep -r "TODO" ./src              # Search recursively in folder&lt;br&gt;
find . -name "*.js"               # Find all JS files&lt;br&gt;
find . -type d -name "models"     # Find directory named "models"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;System Info &amp;amp; Disk&lt;br&gt;
bash&lt;br&gt;
df -h                 # Disk free (human readable)&lt;br&gt;
du -sh folder/        # Size of folder&lt;br&gt;
free -h               # RAM usage&lt;br&gt;
uname -a              # Kernel version&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Network for API Testing&lt;br&gt;
bash&lt;br&gt;
curl &lt;a href="https://api.example.com/users" rel="noopener noreferrer"&gt;https://api.example.com/users&lt;/a&gt;   # GET request&lt;br&gt;
curl -X POST -d '{"name":"John"}' -H "Content-Type: application/json" \&lt;br&gt;
 &lt;a href="https://api.example.com/users" rel="noopener noreferrer"&gt;https://api.example.com/users&lt;/a&gt;&lt;br&gt;
ping google.com       # Check connectivity&lt;br&gt;
netstat -tulpn        # Which ports are listening?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Magic Pipe |&lt;br&gt;
Pipes send output from one command as input to another. This is where Linux becomes powerful.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;bash&lt;br&gt;
ls -la | sort -rk5   # Sort files by size (largest first)&lt;br&gt;
ps aux | grep node | wc -l   # Count Node processes&lt;br&gt;
history | grep docker       # Find a command you ran earlier&lt;br&gt;
One-Liners That Save Hours&lt;br&gt;
bash&lt;/p&gt;

&lt;h1&gt;
  
  
  Find and delete all node_modules folders (frees tons of space)
&lt;/h1&gt;

&lt;p&gt;find . -name "node_modules" -type d -prune -exec rm -rf '{}' +&lt;/p&gt;

&lt;h1&gt;
  
  
  Find largest files in current directory
&lt;/h1&gt;

&lt;p&gt;du -sh * | sort -h | tail -10&lt;/p&gt;

&lt;h1&gt;
  
  
  Replace text in all files
&lt;/h1&gt;

&lt;p&gt;find . -name "*.txt" -exec sed -i 's/old/new/g' {} \;&lt;br&gt;
Bonus: Aliases (Your Best Friend)&lt;br&gt;
Create shortcuts by adding to ~/.bashrc or ~/.zshrc:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
alias gs="git status"&lt;br&gt;
alias ll="ls -la"&lt;br&gt;
alias please="sudo"&lt;br&gt;
alias ..="cd .."&lt;br&gt;
Then run source ~/.bashrc.&lt;/p&gt;

&lt;p&gt;The Golden Rule&lt;br&gt;
Always run ls before rm -rf.&lt;/p&gt;

&lt;p&gt;Accidentally deleting the wrong directory is a rite of passage — but an avoidable one.&lt;/p&gt;

&lt;p&gt;You don’t need to memorize all flags. Use command --help or man command (e.g., man ls). Knowing 80% of these 20 commands will handle 95% of your terminal work.&lt;/p&gt;

&lt;p&gt;What’s your most-used Linux command? Drop it in the comments 👇&lt;/p&gt;

</description>
      <category>linux</category>
      <category>ai</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Localhost vs. Deployment: The Pain is Real It works on my machine (and other lies we tell ourselves)</title>
      <dc:creator>Sohana Akbar</dc:creator>
      <pubDate>Sat, 02 May 2026 13:41:57 +0000</pubDate>
      <link>https://forem.com/sohanaakbar7/localhost-vs-deployment-the-pain-is-real-it-works-on-my-machine-and-other-lies-we-tell-1561</link>
      <guid>https://forem.com/sohanaakbar7/localhost-vs-deployment-the-pain-is-real-it-works-on-my-machine-and-other-lies-we-tell-1561</guid>
      <description>&lt;p&gt;We’ve all been there. Six hours of coding. Green tests. A clean PR.&lt;/p&gt;

&lt;p&gt;You push to production.&lt;/p&gt;

&lt;p&gt;Then it happens. A 500 error. CORS nightmare. Missing asset.&lt;/p&gt;

&lt;p&gt;You whisper the most dangerous sentence in software: “But... it worked on localhost.”&lt;/p&gt;

&lt;p&gt;Welcome to the war.&lt;/p&gt;

&lt;p&gt;The 5 Stages of Localhost Grief&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Environment Variables&lt;br&gt;
Locally: .env works fine.&lt;br&gt;
Production: One missing API_KEY and your entire app implodes with a vague "Internal Server Error."&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Case-Sensitive File Systems&lt;br&gt;
Locally: import User from './components/user' works (thanks, macOS).&lt;br&gt;
Production (Linux): Cannot find module. You cry.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CORS&lt;br&gt;
Locally: localhost:3000 → localhost:5000? No problem.&lt;br&gt;
Production: &lt;a href="https://app.com" rel="noopener noreferrer"&gt;https://app.com&lt;/a&gt; → &lt;a href="https://api.com" rel="noopener noreferrer"&gt;https://api.com&lt;/a&gt;? Denied. Good luck.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Database Divide&lt;br&gt;
Locally: 12 rows. Queries take 2ms.&lt;br&gt;
Production: 12 million rows. No index. That query now takes 45 seconds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;"But the build worked locally"&lt;br&gt;
Until the CI runner uses a different Node patch version and your hash changes. Suddenly, the CSS is gone.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Hard Truth&lt;br&gt;
The gap will never fully close. Cloud changes. Networks lag. Dependencies drift.&lt;/p&gt;

&lt;p&gt;But the pain isn't failure—it's engineering.&lt;/p&gt;

&lt;p&gt;3 Quick Ways to Suffer Less&lt;br&gt;
Use Docker. Develop in the same Linux container you deploy to.&lt;/p&gt;

&lt;p&gt;Kill if (dev) branches. Make local fail as loudly as production.&lt;/p&gt;

&lt;p&gt;Test against real dependencies. Hit the actual API. Use the real CDN.&lt;/p&gt;

&lt;p&gt;What's your worst "works on my machine" story? Drop it below. Let's trauma-bond. 👇&lt;/p&gt;

</description>
      <category>devops</category>
      <category>programming</category>
      <category>softwareengineering</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Add Dark Mode to Any Website (Even If You’re Not a CSS Wizard)</title>
      <dc:creator>Sohana Akbar</dc:creator>
      <pubDate>Fri, 01 May 2026 13:24:19 +0000</pubDate>
      <link>https://forem.com/sohanaakbar7/how-to-add-dark-mode-to-any-website-even-if-youre-not-a-css-wizard-iim</link>
      <guid>https://forem.com/sohanaakbar7/how-to-add-dark-mode-to-any-website-even-if-youre-not-a-css-wizard-iim</guid>
      <description>&lt;p&gt;Introduction&lt;br&gt;
Dark mode isn’t just a trend anymore—it’s an expectation. From Windows and macOS to iOS and Android, users want the option to switch from a blinding white background to a sleek, eye-friendly dark interface.&lt;/p&gt;

&lt;p&gt;But here’s the good news: You don’t need to redesign your entire website. With a few smart CSS rules and a sprinkle of JavaScript, you can add dark mode to any website in under 30 minutes.&lt;/p&gt;

&lt;p&gt;In this article, I’ll show you three methods—from quick-and-dirty to fully professional.&lt;/p&gt;

&lt;p&gt;Method 1: The “Browser Native” Approach (Easiest)&lt;br&gt;
Modern browsers now support prefers-color-scheme, a CSS media query that detects if a user has dark mode enabled in their OS settings.&lt;/p&gt;

&lt;p&gt;Step 1: Add Dark CSS Variables&lt;br&gt;
css&lt;br&gt;
/* Light mode (default) */&lt;br&gt;
:root {&lt;br&gt;
  --bg: #ffffff;&lt;br&gt;
  --text: #111111;&lt;br&gt;
  --accent: #0077cc;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;/* Dark mode automatic */&lt;br&gt;
&lt;a class="mentioned-user" href="https://dev.to/media"&gt;@media&lt;/a&gt; (prefers-color-scheme: dark) {&lt;br&gt;
  :root {&lt;br&gt;
    --bg: #121212;&lt;br&gt;
    --text: #eeeeee;&lt;br&gt;
    --accent: #66ccff;&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;body {&lt;br&gt;
  background: var(--bg);&lt;br&gt;
  color: var(--text);&lt;br&gt;
}&lt;br&gt;
Pros: Zero JavaScript, respects system preferences.&lt;br&gt;
Cons: No manual toggle for users.&lt;/p&gt;

&lt;p&gt;Method 2: Manual Toggle with JavaScript (Most Flexible)&lt;br&gt;
This gives users a button to switch modes, overriding their system preference.&lt;/p&gt;

&lt;p&gt;Step 1: HTML Toggle Button&lt;br&gt;
html&lt;br&gt;
🌓 Dark Mode&lt;br&gt;
Step 2: CSS with a .dark-mode Class&lt;br&gt;
css&lt;br&gt;
:root {&lt;br&gt;
  --bg: #ffffff;&lt;br&gt;
  --text: #111111;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;.dark-mode {&lt;br&gt;
  --bg: #121212;&lt;br&gt;
  --text: #eeeeee;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;body {&lt;br&gt;
  background: var(--bg);&lt;br&gt;
  color: var(--text);&lt;br&gt;
  transition: background 0.3s, color 0.2s;&lt;br&gt;
}&lt;br&gt;
Step 3: JavaScript to Save Preference&lt;br&gt;
javascript&lt;br&gt;
const toggle = document.getElementById('darkModeToggle');&lt;br&gt;
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;&lt;/p&gt;

&lt;p&gt;// Check localStorage or system preference&lt;br&gt;
if (localStorage.getItem('theme') === 'dark' || (!localStorage.getItem('theme') &amp;amp;&amp;amp; prefersDark)) {&lt;br&gt;
  document.body.classList.add('dark-mode');&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;toggle.addEventListener('click', () =&amp;gt; {&lt;br&gt;
  document.body.classList.toggle('dark-mode');&lt;br&gt;
  const theme = document.body.classList.contains('dark-mode') ? 'dark' : 'light';&lt;br&gt;
  localStorage.setItem('theme', theme);&lt;br&gt;
});&lt;br&gt;
Pros: Full user control, persistent choice.&lt;br&gt;
Cons: Requires a bit of JS.&lt;/p&gt;

&lt;p&gt;Method 3: For Legacy Websites (Overriding Inline Styles)&lt;br&gt;
If you’re dealing with messy third-party code or inline styles, use an inverted filter trick (use sparingly).&lt;/p&gt;

&lt;p&gt;css&lt;br&gt;
.dark-mode {&lt;br&gt;
  filter: invert(1) hue-rotate(180deg);&lt;br&gt;
}&lt;br&gt;
How it works: Inverts all colors, then fixes hue shifts. This makes white backgrounds black and black text white.&lt;/p&gt;

&lt;p&gt;Warning: Images and videos will also invert. You’ll need to un-invert them:&lt;/p&gt;

&lt;p&gt;css&lt;br&gt;
.dark-mode img,&lt;br&gt;
.dark-mode video {&lt;br&gt;
  filter: invert(1) hue-rotate(180deg);&lt;br&gt;
}&lt;br&gt;
Only use this as a temporary fix or for simple sites.&lt;/p&gt;

&lt;p&gt;Pro Tips for a High-Quality Dark Mode&lt;br&gt;
Don’t use pure black (#000000) – It creates harsh contrast. Use #121212 or #1e1e1e.&lt;/p&gt;

&lt;p&gt;Reduce shadows – Dark mode looks cleaner with less shadow depth.&lt;/p&gt;

&lt;p&gt;Test all interactive elements – Buttons, links, and inputs must remain accessible.&lt;/p&gt;

&lt;p&gt;Toggle system preference + manual override – Best of both worlds:&lt;/p&gt;

&lt;p&gt;javascript&lt;br&gt;
// Listen to system changes&lt;br&gt;
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) =&amp;gt; {&lt;br&gt;
  if (!localStorage.getItem('theme')) {&lt;br&gt;
    document.body.classList.toggle('dark-mode', e.matches);&lt;br&gt;
  }&lt;br&gt;
});&lt;br&gt;
Real-World Example: Adding Dark Mode to a Blog in 5 Minutes&lt;br&gt;
Let’s say you have a basic WordPress or static HTML site.&lt;/p&gt;

&lt;p&gt;Open your CSS file.&lt;/p&gt;

&lt;p&gt;Define CSS variables for colors.&lt;/p&gt;

&lt;p&gt;Add the .dark-mode class overrides.&lt;/p&gt;

&lt;p&gt;Insert the JavaScript above.&lt;/p&gt;

&lt;p&gt;Add a floating button with position: fixed.&lt;/p&gt;

&lt;p&gt;That’s it. Your blog now has dark mode.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;br&gt;
Dark mode is no longer optional—it’s a mark of a modern, user-respecting website. You don’t need a full rewrite. Start with CSS variables, add a JavaScript toggle, and store the user’s preference in localStorage.&lt;/p&gt;

&lt;p&gt;Whether you manage a personal blog, a corporate site, or a web app, these three methods work everywhere.&lt;/p&gt;

&lt;p&gt;Your users will thank you—especially those coding at 2 AM.&lt;/p&gt;

&lt;p&gt;Ready to go dark?&lt;br&gt;
Try the code snippets above today. Then ask yourself: Why didn’t I do this sooner?&lt;/p&gt;

&lt;p&gt;Let me know if you’d like a ready-to-copy HTML/CSS/JS template for this.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>javascript</category>
      <category>darkmode</category>
    </item>
    <item>
      <title>Responsive CSS Tips That Took Me 6 Months to Learn</title>
      <dc:creator>Sohana Akbar</dc:creator>
      <pubDate>Thu, 30 Apr 2026 14:27:05 +0000</pubDate>
      <link>https://forem.com/sohanaakbar7/responsive-css-tips-that-took-me-6-months-to-learn-2m1h</link>
      <guid>https://forem.com/sohanaakbar7/responsive-css-tips-that-took-me-6-months-to-learn-2m1h</guid>
      <description>&lt;p&gt;After half a year of trial, error, and countless browser tabs, here are the responsive CSS lessons that actually stuck.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Stop using px for everything
px is rigid. rem and em scale with user preferences.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;css&lt;br&gt;
/* Hard to maintain */&lt;br&gt;
body { font-size: 16px; }&lt;/p&gt;

&lt;p&gt;/* Accessible &amp;amp; responsive */&lt;br&gt;
body { font-size: 1rem; }&lt;br&gt;
h1 { font-size: 2.5rem; }&lt;br&gt;
My rule: px for borders, rem for everything text-related.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;clamp() is magic
No more 3 different media queries just to resize a heading.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;css&lt;br&gt;
h1 {&lt;br&gt;
  font-size: clamp(1.5rem, 5vw, 3rem);&lt;br&gt;
}&lt;br&gt;
Fluid typography that scales perfectly from mobile to desktop. One line.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The :has() selector changes everything
Parent selection is finally here.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;css&lt;br&gt;
/* Add padding if card contains an image */&lt;br&gt;
.card:has(img) {&lt;br&gt;
  padding: 1rem;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;/* Highlight a row with an error */&lt;br&gt;
.row:has(.error) {&lt;br&gt;
  background-color: #fff0f0;&lt;br&gt;
}&lt;br&gt;
Works in all modern browsers. Use it carefully—performance is good but not free.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Container queries &amp;gt; Media queries (for components)
Media queries look at the viewport. Container queries look at the component's parent.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;css&lt;br&gt;
.card-container {&lt;br&gt;
  container-type: inline-size;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;@container (min-width: 400px) {&lt;br&gt;
  .card {&lt;br&gt;
    display: flex;&lt;br&gt;
    flex-direction: row;&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
Your card component now responds to its own space, not the whole screen.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;min() and max() for spacing
css
.padding {
padding: min(5vw, 2rem);
}&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;.sidebar {&lt;br&gt;
  width: max(250px, 20%);&lt;br&gt;
}&lt;br&gt;
No media query needed for basic responsive spacing.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;overflow: hidden is not your friend on body
It breaks scroll-driven animations and can cause layout shifts on mobile keyboards.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead, use:&lt;/p&gt;

&lt;p&gt;css&lt;br&gt;
body {&lt;br&gt;
  overflow-x: clip; /* or visible */&lt;br&gt;
}&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Test with real devices, not just DevTools
Chrome's mobile view is optimistic. Real phones have:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Slower touch response&lt;/p&gt;

&lt;p&gt;Notches and dynamic islands&lt;/p&gt;

&lt;p&gt;Zoom settings&lt;/p&gt;

&lt;p&gt;Browser UI that appears/disappears&lt;/p&gt;

&lt;p&gt;Quick test: Grab an old iPhone, Lower brightness to 50%, Open your site in safari. You'll learn more in 5 minutes than an hour in DevTools.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;width: 100% vs width: 100vw
100vw includes scrollbar width. It causes horizontal overflow.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;css&lt;br&gt;
/* This can cause sideways scroll */&lt;br&gt;
.full-width {&lt;br&gt;
  width: 100vw;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;/* Safer */&lt;br&gt;
.full-width {&lt;br&gt;
  width: 100%;&lt;br&gt;
}&lt;br&gt;
The 6-month shortcut&lt;br&gt;
If I could go back, I'd learn in this order:&lt;/p&gt;

&lt;p&gt;rem + clamp() for text&lt;/p&gt;

&lt;p&gt;Container queries for components&lt;/p&gt;

&lt;p&gt;:has() for conditional styling&lt;/p&gt;

&lt;p&gt;min()/max() for spacing&lt;/p&gt;

&lt;p&gt;Real device testing early&lt;/p&gt;

&lt;p&gt;The rest you'll pick up along the way.&lt;/p&gt;

&lt;p&gt;What took you way too long to learn in CSS? Drop it in the comments.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>My First Dockerfile: The Horrifying "Before" vs. The Efficient "After"</title>
      <dc:creator>Sohana Akbar</dc:creator>
      <pubDate>Wed, 29 Apr 2026 12:58:37 +0000</pubDate>
      <link>https://forem.com/sohanaakbar7/my-first-dockerfile-the-horrifying-before-vs-the-efficient-after-5a60</link>
      <guid>https://forem.com/sohanaakbar7/my-first-dockerfile-the-horrifying-before-vs-the-efficient-after-5a60</guid>
      <description>&lt;p&gt;We all have that one commit we’re not proud of. You know, the one pushed late on a Friday night with the message: "pls work".&lt;/p&gt;

&lt;p&gt;For me, that commit contained my very first Dockerfile. I was fresh out of a tutorial, convinced I had mastered containerization. Spoiler: I had not.&lt;/p&gt;

&lt;p&gt;Looking back at that file is like looking at a mullet haircut from 1987. It was functional, but messy, insecure, and bloated.&lt;/p&gt;

&lt;p&gt;Let me show you the evolution. The cringe vs. the clean. The Before vs. the After.&lt;/p&gt;

&lt;p&gt;The "Before": The Wild West Dockerfile&lt;br&gt;
I was building a simple Node.js API. My logic was: Install everything, copy everything, run everything as root, and pray.&lt;/p&gt;

&lt;p&gt;dockerfile&lt;/p&gt;

&lt;h1&gt;
  
  
  Before: The "It works on my machine" special
&lt;/h1&gt;

&lt;p&gt;FROM node:latest&lt;/p&gt;

&lt;h1&gt;
  
  
  Create app directory (Good start, but wait for it...)
&lt;/h1&gt;

&lt;p&gt;WORKDIR /usr/src/app&lt;/p&gt;

&lt;h1&gt;
  
  
  Copy EVERYTHING. Node modules? Yeah, copy those too. .git? Sure.
&lt;/h1&gt;

&lt;p&gt;COPY . .&lt;/p&gt;

&lt;h1&gt;
  
  
  Install dependencies (including dev dependencies, because why not?)
&lt;/h1&gt;

&lt;p&gt;RUN npm install&lt;/p&gt;

&lt;h1&gt;
  
  
  Install global tools nobody asked for
&lt;/h1&gt;

&lt;p&gt;RUN npm install -g nodemon pm2&lt;/p&gt;

&lt;h1&gt;
  
  
  Expose a port (Only one? Let's guess!)
&lt;/h1&gt;

&lt;p&gt;EXPOSE 3000&lt;/p&gt;

&lt;h1&gt;
  
  
  Run as root (Security? Never heard of her)
&lt;/h1&gt;

&lt;p&gt;CMD ["npm", "start"]&lt;br&gt;
Why this made me a monster&lt;br&gt;
node:latest is a ticking time bomb. Today it’s Node 21; next week it’s Node 22. Your build will randomly break because dependencies don’t match.&lt;/p&gt;

&lt;p&gt;COPY . . is lazy and dangerous. I copied node_modules from my host machine (which was built for Windows/Mac) into the Linux container. This causes segfaults and mysterious "module not found" errors. I also copied secrets, SSH keys, and my .env file into the final image.&lt;/p&gt;

&lt;p&gt;Giant image size. My image was ~1.2GB. Pulling that over coffee shop Wi-Fi? Forget it.&lt;/p&gt;

&lt;p&gt;Running as root. If a hacker exploited my Node app, they had full root access to the container. Yikes.&lt;/p&gt;

&lt;p&gt;The "After": The Professional's Approach&lt;br&gt;
After three production outages and a mentor slapping me (metaphorically) with a security scan, I rewrote everything. Here is the Dockerfile I use today.&lt;/p&gt;

&lt;p&gt;dockerfile&lt;/p&gt;

&lt;h1&gt;
  
  
  After: Lean, mean, and secure
&lt;/h1&gt;

&lt;h1&gt;
  
  
  1. Specific version + slim variant
&lt;/h1&gt;

&lt;p&gt;FROM node:20-slim AS dependencies&lt;/p&gt;

&lt;p&gt;WORKDIR /app&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Copy ONLY package files first (Leverage Docker caching)
&lt;/h1&gt;

&lt;p&gt;COPY package*.json ./&lt;br&gt;
RUN npm ci --only=production&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Multi-stage build: Separate build from runtime
&lt;/h1&gt;

&lt;p&gt;FROM node:20-slim AS runtime&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Create a non-root user
&lt;/h1&gt;

&lt;p&gt;RUN groupadd -r nodejs &amp;amp;&amp;amp; useradd -r -g nodejs nodejs&lt;/p&gt;

&lt;p&gt;WORKDIR /app&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Copy only what we need from the previous stage
&lt;/h1&gt;

&lt;p&gt;COPY --from=dependencies --chown=nodejs:nodejs /app/node_modules ./node_modules&lt;br&gt;
COPY --chown=nodejs:nodejs . .&lt;/p&gt;

&lt;h1&gt;
  
  
  6. Security: Drop capabilities &amp;amp; set user
&lt;/h1&gt;

&lt;p&gt;USER nodejs&lt;/p&gt;

&lt;h1&gt;
  
  
  7. Health check so orchestrators know it's alive
&lt;/h1&gt;

&lt;p&gt;HEALTHCHECK --interval=30s --timeout=3s CMD node health.js&lt;/p&gt;

&lt;p&gt;EXPOSE 3000&lt;/p&gt;

&lt;h1&gt;
  
  
  8. Production grade runtime
&lt;/h1&gt;

&lt;p&gt;CMD ["node", "server.js"]&lt;br&gt;
Breaking Down the Differences&lt;br&gt;
Let's put these two files side-by-side in a cage match.&lt;/p&gt;

&lt;p&gt;Feature The "Before" (Horror)   The "After" (Glory)&lt;br&gt;
Base Image  node:latest (floating, dangerous)   node:20-slim (specific, smaller)&lt;br&gt;
Caching Copies everything, invalidates cache always Copies package.json first, then code. Much faster rebuilds.&lt;br&gt;
Permissions Runs as root    Runs as nodejs user&lt;br&gt;
Multi-stage No  Yes (Separates build tools from runtime)&lt;br&gt;
Dependencies    npm install (includes dev dependencies) npm ci --only=production (exact versions, no dev junk)&lt;br&gt;
What's inside   Source code, .git, .env, local node_modules Only the bare necessities&lt;br&gt;
The Actual Metrics (Real numbers from my app)&lt;br&gt;
Metric  Before  After   Improvement&lt;br&gt;
Image Size  1.2 GB  210 MB  83% smaller&lt;br&gt;
Build Time  45 seconds  6 seconds   87% faster&lt;br&gt;
Vulnerabilities (npm audit) 23 high/critical    0   Infinite % better&lt;br&gt;
Container Start Time    3.2 seconds 0.8 seconds 75% faster&lt;br&gt;
The 5 Lessons I Learned (So You Don't Suffer)&lt;br&gt;
If you take nothing else away from this post, remember these five golden rules:&lt;/p&gt;

&lt;p&gt;Never use latest. Pin your versions. node:20-alpine or python:3.11-slim are your friends.&lt;/p&gt;

&lt;p&gt;Leverage layer caching. Copy dependency files before your source code. Docker caches each step. If package.json hasn't changed, Docker reuses the cached npm install. This saves minutes.&lt;/p&gt;

&lt;p&gt;Don't run as root. Add a user. USER appuser. It takes two lines and stops 90% of container exploits.&lt;/p&gt;

&lt;p&gt;Multi-stage builds are magic. One Dockerfile can have multiple FROM statements. Use the first stage to compile/build, the final stage to only run the binary.&lt;/p&gt;

&lt;p&gt;.dockerignore is non-negotiable. The COPY . . is evil. Create a .dockerignore file (same syntax as .gitignore) to exclude node_modules, .git, .env, and Dockerfile itself.&lt;/p&gt;

&lt;p&gt;The Final Verdict&lt;br&gt;
My first Dockerfile was a monolith of mistakes. It was a beginner's rite of passage—like burning toast or accidentally deleting a database in dev.&lt;/p&gt;

&lt;p&gt;But the "after" version? That image is secure, tiny, and fast. It belongs in production.&lt;/p&gt;

&lt;p&gt;Where are you on your Docker journey? Have you committed a "before" Dockerfile recently? Drop it in the comments so we can all cringe together (and then help you fix it).&lt;/p&gt;

&lt;p&gt;Happy containerizing, and may your builds always be cache hits. 🐳&lt;/p&gt;

</description>
      <category>docker</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>What is CI/CD? Explained Like You're 5 (And You Build Sandcastles)</title>
      <dc:creator>Sohana Akbar</dc:creator>
      <pubDate>Tue, 28 Apr 2026 13:50:20 +0000</pubDate>
      <link>https://forem.com/sohanaakbar7/what-is-cicd-explained-like-youre-5-and-you-build-sandcastles-3dp2</link>
      <guid>https://forem.com/sohanaakbar7/what-is-cicd-explained-like-youre-5-and-you-build-sandcastles-3dp2</guid>
      <description>&lt;p&gt;DevOps can sound scary. Let's fix that.&lt;/p&gt;

&lt;p&gt;Imagine you love building sandcastles on the beach.&lt;/p&gt;

&lt;p&gt;The Old Way (No CI/CD)&lt;br&gt;
You spend 3 hours building a huge castle with towers and a moat. You don't show anyone until it's "done."&lt;/p&gt;

&lt;p&gt;Then, the wave comes. Your castle falls apart. You cry. You have to start all over. 😭&lt;/p&gt;

&lt;p&gt;The CI/CD Way&lt;br&gt;
CI = Continuous Integration&lt;br&gt;
This means: Add a little bit of sand, then check if it's still good.&lt;/p&gt;

&lt;p&gt;Every 5 minutes, you add one new bucket of sand. Then you splash a little water to test if it stays firm. If it breaks? You fix it immediately while it's still small.&lt;/p&gt;

&lt;p&gt;For adults: Developers merge small code changes often, and automated tests run every time.&lt;/p&gt;

&lt;p&gt;CD = Continuous Delivery/Deployment&lt;br&gt;
This means: As soon as a new piece is ready, put it on the castle automatically.&lt;/p&gt;

&lt;p&gt;You finish one tower? Poof — a tiny helper (robot) places it on the real castle for everyone to see. No waiting.&lt;/p&gt;

&lt;p&gt;For adults: Every change that passes tests is automatically released to users.&lt;/p&gt;

&lt;p&gt;Why is this good?&lt;br&gt;
No more all-nighters fixing giant messes. (Fix small problems as they happen.)&lt;/p&gt;

&lt;p&gt;Your castle is always standing. (The software is always working.)&lt;/p&gt;

&lt;p&gt;New towers arrive instantly. (Users get features faster.)&lt;/p&gt;

&lt;p&gt;The Golden Rule&lt;br&gt;
Small sand, often. Test always. Wave? No problem.&lt;/p&gt;

&lt;p&gt;That's CI/CD. Now go build something that won't wash away. 🏰&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.S. If a 5-year-old can get it, so can your team.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cicd</category>
      <category>devops</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Git commands I use daily (cheatsheet)</title>
      <dc:creator>Sohana Akbar</dc:creator>
      <pubDate>Mon, 27 Apr 2026 15:18:36 +0000</pubDate>
      <link>https://forem.com/sohanaakbar7/git-commands-i-use-daily-cheatsheet-54dh</link>
      <guid>https://forem.com/sohanaakbar7/git-commands-i-use-daily-cheatsheet-54dh</guid>
      <description>&lt;p&gt;Most Git tutorials throw an encyclopedia at you. But in reality, you’ll use the same ~10 commands every single day.&lt;/p&gt;

&lt;p&gt;Here’s my no-fluff daily cheatsheet.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The absolute basics
bash
git clone    # Download a repo
git status             # What changed?
git add .              # Stage everything
git commit -m "fix: message"  # Save changes&lt;/li&gt;
&lt;li&gt;Working with remotes
bash
git pull --rebase      # Get latest changes (cleaner history)
git push               # Upload your commits
git fetch              # See what changed without merging&lt;/li&gt;
&lt;li&gt;Branching (daily)
bash
git branch              # List branches (* = current)
git checkout -b feat/x  # Create + switch to new branch
git switch main         # Switch to main (newer syntax)
git branch -d old-branch # Delete local branch&lt;/li&gt;
&lt;li&gt;Fixing mistakes (no panic)
bash
git commit --amend -m "new message"  # Edit last commit
git reset HEAD~1        # Undo last commit (keep changes)
git restore file.js     # Discard unstaged changes
git restore --staged .  # Unstage everything&lt;/li&gt;
&lt;li&gt;Seeing what happened
bash
git log --oneline --graph  # Pretty commit tree
git diff                   # Unstaged changes
git diff --staged          # Staged changes&lt;/li&gt;
&lt;li&gt;The one "advanced" command I use daily
bash
git reflog   # Show EVERYTHING you did (undo any mistake)
Pro tip: Aliases
Add these to ~/.gitconfig:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;bash&lt;br&gt;
git config --global alias.co checkout&lt;br&gt;
git config --global alias.br branch&lt;br&gt;
git config --global alias.st status&lt;br&gt;
git config --global alias.lg "log --oneline --graph"&lt;br&gt;
Now git st, git co main, git lg — saves hours.&lt;/p&gt;

&lt;p&gt;Bottom line: You don’t need 50 commands. Master these, and you’re productive.&lt;/p&gt;

&lt;p&gt;What’s your most-used Git command? 👇&lt;/p&gt;

</description>
      <category>git</category>
      <category>productivity</category>
      <category>beginners</category>
      <category>cheatsheet</category>
    </item>
  </channel>
</rss>
