<?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: Bishop Abraham</title>
    <description>The latest articles on Forem by Bishop Abraham (@abrahambishopcodes).</description>
    <link>https://forem.com/abrahambishopcodes</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%2F2230727%2Fd81a70e5-11fe-4d63-8fe4-894a9faba669.png</url>
      <title>Forem: Bishop Abraham</title>
      <link>https://forem.com/abrahambishopcodes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/abrahambishopcodes"/>
    <language>en</language>
    <item>
      <title>January 1, 1970 is a very special date in programming. Not because anything groundbreaking happened that day (no revolutionary app launched, no tech billionaire was born), but what really happened is a mind-blowing fact.</title>
      <dc:creator>Bishop Abraham</dc:creator>
      <pubDate>Fri, 17 Oct 2025 20:13:55 +0000</pubDate>
      <link>https://forem.com/abrahambishopcodes/january-1-1970-is-a-very-special-date-in-programming-not-because-anything-groundbreaking-happened-12nm</link>
      <guid>https://forem.com/abrahambishopcodes/january-1-1970-is-a-very-special-date-in-programming-not-because-anything-groundbreaking-happened-12nm</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/abrahambishopcodes/why-january-1-1970-is-the-most-important-date-in-programming-and-youve-probably-never-heard-of-414i" class="crayons-story__hidden-navigation-link"&gt;Why January 1, 1970 Is the Most Important Date in programming (And You've Probably Never Heard of It)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/abrahambishopcodes" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F2230727%2Fd81a70e5-11fe-4d63-8fe4-894a9faba669.png" alt="abrahambishopcodes profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/abrahambishopcodes" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Bishop Abraham
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Bishop Abraham
                
              
              &lt;div id="story-author-preview-content-2934958" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/abrahambishopcodes" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F2230727%2Fd81a70e5-11fe-4d63-8fe4-894a9faba669.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Bishop Abraham&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/abrahambishopcodes/why-january-1-1970-is-the-most-important-date-in-programming-and-youve-probably-never-heard-of-414i" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 17 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/abrahambishopcodes/why-january-1-1970-is-the-most-important-date-in-programming-and-youve-probably-never-heard-of-414i" id="article-link-2934958"&gt;
          Why January 1, 1970 Is the Most Important Date in programming (And You've Probably Never Heard of It)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/computerscience"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;computerscience&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/technology"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;technology&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/software"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;software&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/abrahambishopcodes/why-january-1-1970-is-the-most-important-date-in-programming-and-youve-probably-never-heard-of-414i" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;6&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/abrahambishopcodes/why-january-1-1970-is-the-most-important-date-in-programming-and-youve-probably-never-heard-of-414i#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              2&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>programming</category>
      <category>computerscience</category>
      <category>technology</category>
      <category>software</category>
    </item>
    <item>
      <title>Why January 1, 1970 Is the Most Important Date in programming (And You've Probably Never Heard of It)</title>
      <dc:creator>Bishop Abraham</dc:creator>
      <pubDate>Fri, 17 Oct 2025 18:51:01 +0000</pubDate>
      <link>https://forem.com/abrahambishopcodes/why-january-1-1970-is-the-most-important-date-in-programming-and-youve-probably-never-heard-of-414i</link>
      <guid>https://forem.com/abrahambishopcodes/why-january-1-1970-is-the-most-important-date-in-programming-and-youve-probably-never-heard-of-414i</guid>
      <description>&lt;p&gt;January 1, 1970 is a very special date in programming. Not because anything groundbreaking happened that day (no revolutionary app launched, no tech billionaire was born), but because it's literally the moment time began for computers.&lt;/p&gt;

&lt;p&gt;Every timestamp on your device, from the moment you created that embarrassing selfie to when you last ordered pizza at 2 AM, is secretly just counting seconds from this one specific moment: midnight on January 1, 1970.&lt;/p&gt;

&lt;p&gt;Your computer doesn't think it's October 2025. It thinks it's been exactly 1,770,000,000-ish seconds since New Year's Day 1970.&lt;/p&gt;

&lt;p&gt;Welcome to Unix Epoch Time, the invisible clock that runs the internet.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Even Is Unix Time?
&lt;/h2&gt;

&lt;p&gt;Okay, imagine if everyone measured their age not in years, but in seconds since some random Tuesday in 1970. Weird, right? But that's basically what computers do.&lt;/p&gt;

&lt;p&gt;Unix time (also called Epoch time or POSIX time) is just a giant counter. At the stroke of midnight on January 1, 1970 (UTC, because even time zones can't agree on anything), the counter started at zero. Every second that passes, the number goes up by one. Right now, as you're reading this, the Unix timestamp is somewhere around 1,770,000,000. That's 1.77 &lt;em&gt;billion&lt;/em&gt; seconds of existence.&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%2Fdxyaw0a3uh7i70c02bj9.gif" 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%2Fdxyaw0a3uh7i70c02bj9.gif" alt="div" width="540" height="540"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;When you check the "last modified" date on a file, your computer isn't storing "October 10, 2025, 3:42 PM." That would be messy. Different languages write dates differently (is it 10/10/2025 or 10.10.2025?), and don't even get me started on time zones. Instead, it stores something like &lt;code&gt;1728574920&lt;/code&gt; and then translates it back into a human-readable date when you need to see it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why 1970? Why Not, Like, Year Zero?
&lt;/h2&gt;

&lt;p&gt;Great question. The answer is both practical and deeply nerdy.&lt;/p&gt;

&lt;p&gt;Unix (the operating system that basically runs everything) was developed at Bell Labs in 1969. The developers needed a reference point for their timekeeping system, and they wanted something recent enough to be relevant but round enough to be simple. They picked January 1, 1970 because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;It was close to when they were building the system&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It was the start of a new decade (humans love round numbers)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It made the math easier since they could use 32-bit integers&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nobody thought we'd still be using this system 50+ years later. They just needed &lt;em&gt;something&lt;/em&gt; that worked. And honestly? It worked so well that we're stuck with it forever now.&lt;/p&gt;

&lt;h2&gt;
  
  
  How This Actually Shows Up in Your Code
&lt;/h2&gt;

&lt;p&gt;If you've ever written JavaScript, you've met Unix time whether you knew it or not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// Returns something like: 1728574920000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That number? Milliseconds since January 1, 1970. JavaScript uses milliseconds instead of seconds (because JavaScript likes to be &lt;em&gt;extra&lt;/em&gt;), so you get an even bigger number.&lt;/p&gt;

&lt;p&gt;Want to see what time it was exactly 1 billion seconds after the Unix Epoch?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000000000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Sun Sep 09 2001 01:46:40 GMT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yep, the billionth second happened in 2001. There were parties. Nerds are fun like that.&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%2Fvqheh1rtosqfcby8e9t9.gif" 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%2Fvqheh1rtosqfcby8e9t9.gif" alt="div" width="480" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Python does it too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;# Returns something like: 1728574920.547
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is super useful for things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Sorting events chronologically (bigger number = happened later)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Calculating time differences (just subtract two numbers)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Storing timestamps in databases (one integer instead of a messy date string)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Making sure your API calls don't arrive from the "future" due to clock drift&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When Unix Time Gets Weird
&lt;/h2&gt;

&lt;p&gt;Here's where things get fun. Or terrifying, depending on how you feel about bugs.&lt;/p&gt;

&lt;h3&gt;
  
  
  The December 31, 1969 Mystery
&lt;/h3&gt;

&lt;p&gt;Ever seen a file or app that claims something happened on December 31, 1969? That's Unix time having an existential crisis.&lt;/p&gt;

&lt;p&gt;When a timestamp is &lt;code&gt;0&lt;/code&gt; (or negative, or undefined), and your computer tries to display it in a time zone that's behind UTC, it rolls back to December 31, 1969. It's like the computer is saying, "I have no idea when this happened, so here's the day before time began."&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%2Fcy91nlzfy3cheskf9u4b.gif" 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%2Fcy91nlzfy3cheskf9u4b.gif" alt="div" width="480" height="270"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  The Year 2038 Problem (Coming Soon to a Server Near You)
&lt;/h3&gt;

&lt;p&gt;Remember how I said Unix time uses 32-bit integers? Well, those can only count so high: 2,147,483,647 to be exact.&lt;/p&gt;

&lt;p&gt;That number will be reached at exactly 03:14:07 UTC on January 19, 2038.&lt;/p&gt;

&lt;p&gt;And then? The counter overflows and wraps back around to... December 13, 1901.&lt;/p&gt;

&lt;p&gt;This is called the Year 2038 problem, and it's basically Y2K's cooler, scarier younger sibling. Old systems still running on 32-bit integers will absolutely lose their minds. Banking software, embedded systems, legacy servers, anything that hasn't been updated to use 64-bit integers could suddenly think it's the early 1900s.&lt;/p&gt;

&lt;p&gt;The good news? Most modern systems have already switched to 64-bit timestamps, which won't run out until the year 292,277,026,596. So unless you're planning to still be debugging code in 292 billion years, you're probably fine.&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%2F03d4owue9869s7s0h8jc.gif" 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%2F03d4owue9869s7s0h8jc.gif" alt="div" width="480" height="480"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Leap Seconds: Unix Time's Awkward Cousin
&lt;/h3&gt;

&lt;p&gt;Here's something that'll blow your mind: Unix time completely ignores leap seconds.&lt;/p&gt;

&lt;p&gt;Earth's rotation isn't perfectly consistent, so occasionally scientists add a "leap second" to keep our clocks in sync with the planet's actual rotation. But Unix time? It just pretends leap seconds don't exist. It assumes every day has exactly 86,400 seconds, no exceptions.&lt;/p&gt;

&lt;p&gt;This means Unix time is technically &lt;em&gt;lying&lt;/em&gt; to you by about 27 seconds right now. But it's a useful lie because dealing with random extra seconds would make timestamps way more complicated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters to You (Yes, Even You)
&lt;/h2&gt;

&lt;p&gt;You might be thinking, "Cool story, but I don't write low-level system code. Why should I care?"&lt;/p&gt;

&lt;p&gt;Because Unix time is everywhere, and understanding it helps you avoid really annoying bugs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Time zone disasters:&lt;/strong&gt; Ever had a user report that your app shows the wrong date? Probably because you forgot to account for time zones when converting Unix timestamps. Always store times in UTC (Unix time already is), then convert to local time only when displaying to users.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Date comparison fails:&lt;/strong&gt; If you're comparing dates by converting them to strings like "2025-10-10", you're doing it wrong. Convert to Unix timestamps and compare the numbers. Way more reliable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API authentication:&lt;/strong&gt; Many APIs use timestamps in their authentication signatures to prevent replay attacks. If your system clock is off by even a few seconds, your requests might get rejected for being "from the future" or "too old."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cache invalidation:&lt;/strong&gt; When you're caching data with expiration times, you're almost certainly using Unix timestamps under the hood. Understanding how they work helps you debug when cached data sticks around too long (or expires too soon).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Beautiful Simplicity of It All
&lt;/h2&gt;

&lt;p&gt;At the end of the day, Unix time is just really good design. It's simple, universal, and mostly foolproof.&lt;/p&gt;

&lt;p&gt;Instead of dealing with the nightmare of "Is it October 10 or 10 October?" and "Wait, does this month have 30 or 31 days?" and "What even is daylight saving time?", we just count seconds. One number. That's it.&lt;/p&gt;

&lt;p&gt;Sure, it has quirks (looking at you, 2038 problem), but it's been working reliably for over 50 years. That's pretty impressive for something that was probably sketched out on a napkin at Bell Labs in 1969.&lt;/p&gt;

&lt;p&gt;So next time you see a timestamp in your code or a weird date bug pops up, remember: somewhere deep in your computer's soul, it's just counting seconds from that magical moment at midnight on January 1, 1970.&lt;/p&gt;

&lt;p&gt;Time really does fly when you're having fun. Or when you're a Unix timestamp, at least.&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%2Fd95qtc03rmypuz0tvjoa.gif" 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%2Fd95qtc03rmypuz0tvjoa.gif" alt="div" width="480" height="202"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you ever encountered a weird Unix timestamp bug? Drop your stories in the comments. Bonus points if it involved December 31, 1969.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Originally published on &lt;a href="https://abraham-bishop.hashnode.dev/why-january-1-1970-is-the-most-important-date-in-programming-and-youve-probably-never-heard-of-it" rel="noopener noreferrer"&gt;My Blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>computerscience</category>
      <category>technology</category>
      <category>software</category>
    </item>
    <item>
      <title>Most of the time, your IP address just quietly does its job. But in the wrong hands? Things get interesting. And by interesting, I mean potentially bad.</title>
      <dc:creator>Bishop Abraham</dc:creator>
      <pubDate>Thu, 16 Oct 2025 08:21:57 +0000</pubDate>
      <link>https://forem.com/abrahambishopcodes/most-of-the-time-your-ip-address-just-quietly-does-its-job-but-in-the-wrong-hands-things-get-53c8</link>
      <guid>https://forem.com/abrahambishopcodes/most-of-the-time-your-ip-address-just-quietly-does-its-job-but-in-the-wrong-hands-things-get-53c8</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/abrahambishopcodes/how-hackers-use-your-ip-address-and-why-you-should-actually-care-570j" class="crayons-story__hidden-navigation-link"&gt;How Hackers Use Your IP Address (And Why You Should Actually Care)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/abrahambishopcodes" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F2230727%2Fd81a70e5-11fe-4d63-8fe4-894a9faba669.png" alt="abrahambishopcodes profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/abrahambishopcodes" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Bishop Abraham
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Bishop Abraham
                
              
              &lt;div id="story-author-preview-content-2929527" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/abrahambishopcodes" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F2230727%2Fd81a70e5-11fe-4d63-8fe4-894a9faba669.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Bishop Abraham&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/abrahambishopcodes/how-hackers-use-your-ip-address-and-why-you-should-actually-care-570j" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 16 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/abrahambishopcodes/how-hackers-use-your-ip-address-and-why-you-should-actually-care-570j" id="article-link-2929527"&gt;
          How Hackers Use Your IP Address (And Why You Should Actually Care)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cybersecurity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cybersecurity&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/internet"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;internet&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/networking"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;networking&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/software"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;software&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/abrahambishopcodes/how-hackers-use-your-ip-address-and-why-you-should-actually-care-570j" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/fire-f60e7a582391810302117f987b22a8ef04a2fe0df7e3258a5f49332df1cec71e.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;8&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/abrahambishopcodes/how-hackers-use-your-ip-address-and-why-you-should-actually-care-570j#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              1&lt;span class="hidden s:inline"&gt; comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>cybersecurity</category>
      <category>internet</category>
      <category>networking</category>
      <category>software</category>
    </item>
    <item>
      <title>How Hackers Use Your IP Address (And Why You Should Actually Care)</title>
      <dc:creator>Bishop Abraham</dc:creator>
      <pubDate>Thu, 16 Oct 2025 08:20:50 +0000</pubDate>
      <link>https://forem.com/abrahambishopcodes/how-hackers-use-your-ip-address-and-why-you-should-actually-care-570j</link>
      <guid>https://forem.com/abrahambishopcodes/how-hackers-use-your-ip-address-and-why-you-should-actually-care-570j</guid>
      <description>&lt;p&gt;Let's talk about something we all have but don't really think about: our IP address.&lt;/p&gt;

&lt;p&gt;It's basically your internet phone number. Every device connected to the internet gets one. Your laptop, phone, smart TV, and yes, even that smart fridge nobody asked for but somehow exists.&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%2Frmnllgzbws0pnj1ko3pz.gif" 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%2Frmnllgzbws0pnj1ko3pz.gif" alt="gif" width="313" height="305"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Most of the time, your IP address just quietly does its job. But in the wrong hands? Things get interesting. And by interesting, I mean potentially bad.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Hackers Can Actually Do With Your IP
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Track Your General Location
&lt;/h3&gt;

&lt;p&gt;No, they can't see your exact address (this isn't a spy movie). But they CAN see your city and internet provider.&lt;/p&gt;

&lt;p&gt;Which means that phishing email saying "We noticed suspicious activity on your account from [your actual city]" just got way more convincing, didn't it?&lt;/p&gt;

&lt;p&gt;It's like someone saying "I know where you live" but they only know your neighborhood. Still creepy enough to make you nervous.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Knock on Your Digital Doors
&lt;/h3&gt;

&lt;p&gt;Hackers scan your IP looking for open ports. Running a home server? Remote desktop enabled? Old device you forgot about?&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%2Fokxj8wcpwn7kms48ixzn.gif" 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%2Fokxj8wcpwn7kms48ixzn.gif" alt="gif" width="500" height="281"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;They'll find it. And if you left it unlocked, congrats, they're in.&lt;/p&gt;

&lt;p&gt;It's the digital equivalent of someone walking down your street jiggling every door handle to see who forgot to lock up.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Flood You Offline (DDoS)
&lt;/h3&gt;

&lt;p&gt;Ever seen a streamer suddenly go offline mid-game? Or a website just... die?&lt;/p&gt;

&lt;p&gt;That's a DDoS attack. Someone floods your IP with so much fake traffic that your connection gives up and collapses.&lt;/p&gt;

&lt;p&gt;It's like a thousand people calling your phone simultaneously. Eventually, nobody's getting through. Including you.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Hijack Your Router or Smart Devices
&lt;/h3&gt;

&lt;p&gt;Here's the fun part: tons of routers still use "admin/admin" or "password" as the default login.&lt;/p&gt;

&lt;p&gt;If yours does and it's exposed to the internet, congratulations! Your router just became part of someone's botnet army. Your Ring doorbell is now helping attack a Minecraft server halfway across the world.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Brute Force Your Login Pages
&lt;/h3&gt;

&lt;p&gt;Got a login portal on your network? Maybe a home NAS or remote desktop?&lt;/p&gt;

&lt;p&gt;Hackers will throw every leaked password from every data breach at it until something clicks. And trust me, they've got a LOT of leaked passwords.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Your IP WON'T Reveal
&lt;/h2&gt;

&lt;p&gt;Let's kill some myths real quick.&lt;/p&gt;

&lt;p&gt;Your IP address alone won't show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Your name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your exact street address&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your bank details&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your browser history&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What you ordered on Amazon last night&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's not magic. It's just a number.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But&lt;/strong&gt; combine it with leaked info, some social media stalking, and a convincing phone call? Now you're in trouble.&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%2Foumxn9he5kpi52cg71k0.gif" 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%2Foumxn9he5kpi52cg71k0.gif" alt="gif" width="300" height="300"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  How to Not Be an Easy Target
&lt;/h2&gt;

&lt;p&gt;You don't need to be a cybersecurity expert. Just do these:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use a VPN on public Wi-Fi.&lt;/strong&gt; Coffee shop internet is basically an open buffet for hackers. A VPN hides your real IP and locks down your traffic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update your router.&lt;/strong&gt; Yes, it's boring. Yes, that firmware update might actually save you from getting hacked. Do it anyway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Change. Default. Passwords.&lt;/strong&gt; If your router login is still "admin/password," stop reading and go change it right now. Seriously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Turn off remote features you don't use.&lt;/strong&gt; Don't know what UPnP or remote admin does? You probably don't need it facing the internet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lock down what you expose.&lt;/strong&gt; Home server? Cool. Leaving it wide open with no firewall? Not cool.&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%2F79gkrcv7m1evskbmiffn.gif" 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%2F79gkrcv7m1evskbmiffn.gif" alt="gif" width="470" height="328"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Talk
&lt;/h2&gt;

&lt;p&gt;Your IP isn't dangerous by itself. It's just information.&lt;/p&gt;

&lt;p&gt;But hand that information to someone who knows what they're doing and has bad intentions? It becomes a weapon. A starting point. The crack in your armor.&lt;/p&gt;

&lt;p&gt;You wouldn't leave your front door wide open with a neon sign saying "FREE STUFF INSIDE." Don't do the internet equivalent.&lt;/p&gt;

&lt;p&gt;A few simple steps make you way harder to mess with. And in cybersecurity, not being the easiest target is literally 80% of the game.&lt;/p&gt;

&lt;p&gt;The hackers will just move on to the next person who's still using "password123."&lt;/p&gt;

&lt;p&gt;Don't be that person.&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%2Frw0wbqw3dlq8phxaexad.gif" 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%2Frw0wbqw3dlq8phxaexad.gif" alt="gif" width="480" height="254"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be honest: have you changed your router password since you got it? Or are you still rocking the defaults? Drop a comment, no judgment... okay, maybe a little judgment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Originally published on &lt;a href="https://abraham-bishop.hashnode.dev/" rel="noopener noreferrer"&gt;My Blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>internet</category>
      <category>networking</category>
      <category>software</category>
    </item>
    <item>
      <title>After deploying your react app on Vercel, you're sitting there like "It literally worked two seconds ago. I didn't change anything. What is happening?"

Let me explain what's going on, and more importantly, how to fix it without losing your mind.</title>
      <dc:creator>Bishop Abraham</dc:creator>
      <pubDate>Mon, 13 Oct 2025 23:42:06 +0000</pubDate>
      <link>https://forem.com/abrahambishopcodes/after-deploying-your-react-app-on-vercel-youre-sitting-there-like-it-literally-worked-two-1plk</link>
      <guid>https://forem.com/abrahambishopcodes/after-deploying-your-react-app-on-vercel-youre-sitting-there-like-it-literally-worked-two-1plk</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/abrahambishopcodes/why-your-react-app-breaks-when-you-refresh-on-vercel-and-the-2-minute-fix-1991" class="crayons-story__hidden-navigation-link"&gt;Why Your React App Breaks When You Refresh on Vercel (And the 2-Minute Fix)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/abrahambishopcodes" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F2230727%2Fd81a70e5-11fe-4d63-8fe4-894a9faba669.png" alt="abrahambishopcodes profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/abrahambishopcodes" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Bishop Abraham
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Bishop Abraham
                
              
              &lt;div id="story-author-preview-content-2921573" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/abrahambishopcodes" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F2230727%2Fd81a70e5-11fe-4d63-8fe4-894a9faba669.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Bishop Abraham&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/abrahambishopcodes/why-your-react-app-breaks-when-you-refresh-on-vercel-and-the-2-minute-fix-1991" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 13 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/abrahambishopcodes/why-your-react-app-breaks-when-you-refresh-on-vercel-and-the-2-minute-fix-1991" id="article-link-2921573"&gt;
          Why Your React App Breaks When You Refresh on Vercel (And the 2-Minute Fix)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/react"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;react&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/vercel"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;vercel&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/deployment"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;deployment&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/abrahambishopcodes/why-your-react-app-breaks-when-you-refresh-on-vercel-and-the-2-minute-fix-1991" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;5&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/abrahambishopcodes/why-your-react-app-breaks-when-you-refresh-on-vercel-and-the-2-minute-fix-1991#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              2&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>react</category>
      <category>vercel</category>
      <category>deployment</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why Your React App Breaks When You Refresh on Vercel (And the 2-Minute Fix)</title>
      <dc:creator>Bishop Abraham</dc:creator>
      <pubDate>Mon, 13 Oct 2025 23:37:55 +0000</pubDate>
      <link>https://forem.com/abrahambishopcodes/why-your-react-app-breaks-when-you-refresh-on-vercel-and-the-2-minute-fix-1991</link>
      <guid>https://forem.com/abrahambishopcodes/why-your-react-app-breaks-when-you-refresh-on-vercel-and-the-2-minute-fix-1991</guid>
      <description>&lt;p&gt;So you finally deploy your React app to Vercel. It works. You click around, everything's smooth. Then you navigate to another page, hit refresh and…&lt;/p&gt;

&lt;p&gt;Boom. 404 Page Not Found.&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%2F9rwht7myd5yocawewur9.gif" 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%2F9rwht7myd5yocawewur9.gif" alt="gif" width="300" height="224"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;You're sitting there like "It literally worked two seconds ago. I didn't change anything. What is happening?"&lt;/p&gt;

&lt;p&gt;Let me explain what's going on, and more importantly, how to fix it without losing your mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Actually Happening Here
&lt;/h2&gt;

&lt;p&gt;Your React app uses React Router to handle navigation. When you click a link to &lt;code&gt;/about&lt;/code&gt; or &lt;code&gt;/profile&lt;/code&gt;, React quietly swaps the content on your screen without actually loading a new page from the server. It's smooth, it's fast, it's great.&lt;/p&gt;

&lt;p&gt;But here's the problem.&lt;/p&gt;

&lt;p&gt;When you hit refresh on &lt;code&gt;/about&lt;/code&gt;, your browser asks Vercel's server: "Hey, give me the &lt;code&gt;/about&lt;/code&gt; page."&lt;/p&gt;

&lt;p&gt;And Vercel's like: "About? I don't have a file or folder called 'about.' Here's a 404 instead."&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%2Fbpl9fyk6g6dpdald17km.gif" 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%2Fbpl9fyk6g6dpdald17km.gif" alt="gif" width="400" height="400"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;See, Vercel is looking for actual files and folders. But &lt;code&gt;/about&lt;/code&gt; doesn't exist as a file. It only exists in your React Router configuration, which lives in JavaScript that hasn't run yet because... well, you got a 404 before React could even load.&lt;/p&gt;

&lt;p&gt;Classic catch-22.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix (Seriously, Takes 2 Minutes)
&lt;/h2&gt;

&lt;p&gt;You need to tell Vercel: "Listen, no matter what URL someone visits, just serve them the main React app. Let React figure out the routing."&lt;/p&gt;

&lt;p&gt;Here's how:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; In your project folder (where &lt;code&gt;package.json&lt;/code&gt; lives), create a file called &lt;code&gt;vercel.json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Paste this in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rewrites"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/(.*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Save it. Push to GitHub (or wherever your code lives).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; Redeploy on Vercel.&lt;/p&gt;

&lt;p&gt;That's it. Go test it. Navigate to any page, hit refresh. It works now.&lt;/p&gt;

&lt;p&gt;What this config does is tell Vercel "For every route someone tries to access, serve them the main index.html file." Then React Router takes over and shows the right page.&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%2Fzkzs0j73uba8k9sdluzw.gif" 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%2Fzkzs0j73uba8k9sdluzw.gif" alt="gif" width="480" height="270"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  The Quick-and-Dirty Alternative
&lt;/h2&gt;

&lt;p&gt;If you're in a rush and don't want to mess with config files, there's another option.&lt;/p&gt;

&lt;p&gt;Change this in your code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BrowserRouter&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="s2"&gt;react-router-dom&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;To this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HashRouter&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="s2"&gt;react-router-dom&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;This makes your URLs look like &lt;code&gt;/#/about&lt;/code&gt; instead of &lt;code&gt;/about&lt;/code&gt;. The refresh issue goes away, but your URLs are uglier and search engines don't love them.&lt;/p&gt;

&lt;p&gt;It's like fixing a broken chair by just sitting on the floor. Technically works, but not ideal.&lt;/p&gt;

&lt;p&gt;Use this only if you're desperate or don't have access to deploy config files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Happens to Everyone
&lt;/h2&gt;

&lt;p&gt;You didn't mess up. This trips up tons of developers, even experienced ones.&lt;/p&gt;

&lt;p&gt;It's just one of those things where your local development environment and production hosting don't work the same way. On your local machine with &lt;code&gt;npm start&lt;/code&gt;, the dev server handles this automatically. But when you deploy? Different story.&lt;/p&gt;

&lt;p&gt;Now you know. And next time someone in your Discord or Slack freaks out about this exact issue, you can swoop in with the answer and look like a genius.&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%2Fibl3ysk8y1p6hk1sf8l6.gif" 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%2Fibl3ysk8y1p6hk1sf8l6.gif" alt="gif" width="245" height="195"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaway
&lt;/h2&gt;

&lt;p&gt;Single Page Apps (SPAs) like React are amazing, but they need a little help when it comes to server-side routing. One tiny config file fixes it permanently.&lt;/p&gt;

&lt;p&gt;Bookmark this post. You'll probably need it again, or someone you know will.&lt;/p&gt;

&lt;p&gt;Got other React deployment headaches? Drop them in the comments. I've probably run into them too, and misery loves company.&lt;/p&gt;

&lt;p&gt;Now go refresh that page with confidence.&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%2F2sjvk465xftrnr8moglv.gif" 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%2F2sjvk465xftrnr8moglv.gif" alt="gif" width="600" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Originally published on &lt;a href="https://abraham-bishop.hashnode.dev/" rel="noopener noreferrer"&gt;My Blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>vercel</category>
      <category>deployment</category>
      <category>webdev</category>
    </item>
    <item>
      <title>And after four years of building projects, I've figured out which tools actually matter.

Not the trendy ones. The ones that save my sanity when production is on fire.</title>
      <dc:creator>Bishop Abraham</dc:creator>
      <pubDate>Mon, 13 Oct 2025 00:42:03 +0000</pubDate>
      <link>https://forem.com/abrahambishopcodes/and-after-four-years-of-building-projects-ive-figured-out-which-tools-actually-matter-not-the-1npm</link>
      <guid>https://forem.com/abrahambishopcodes/and-after-four-years-of-building-projects-ive-figured-out-which-tools-actually-matter-not-the-1npm</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/abrahambishopcodes/the-mern-stack-tools-i-actually-use-not-just-the-ones-that-look-good-on-twitter-31lo" class="crayons-story__hidden-navigation-link"&gt;🛠 The MERN Stack Tools I Actually Use (Not Just the Ones That Look Good on Twitter)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/abrahambishopcodes" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F2230727%2Fd81a70e5-11fe-4d63-8fe4-894a9faba669.png" alt="abrahambishopcodes profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/abrahambishopcodes" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Bishop Abraham
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Bishop Abraham
                
              
              &lt;div id="story-author-preview-content-2918479" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/abrahambishopcodes" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F2230727%2Fd81a70e5-11fe-4d63-8fe4-894a9faba669.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Bishop Abraham&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/abrahambishopcodes/the-mern-stack-tools-i-actually-use-not-just-the-ones-that-look-good-on-twitter-31lo" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Oct 13 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/abrahambishopcodes/the-mern-stack-tools-i-actually-use-not-just-the-ones-that-look-good-on-twitter-31lo" id="article-link-2918479"&gt;
          🛠 The MERN Stack Tools I Actually Use (Not Just the Ones That Look Good on Twitter)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/productivity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;productivity&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devtools"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devtools&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devtips"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devtips&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/abrahambishopcodes/the-mern-stack-tools-i-actually-use-not-just-the-ones-that-look-good-on-twitter-31lo" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;6&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/abrahambishopcodes/the-mern-stack-tools-i-actually-use-not-just-the-ones-that-look-good-on-twitter-31lo#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              2&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>productivity</category>
      <category>devtools</category>
      <category>devtips</category>
      <category>programming</category>
    </item>
    <item>
      <title>🛠 The MERN Stack Tools I Actually Use (Not Just the Ones That Look Good on Twitter)</title>
      <dc:creator>Bishop Abraham</dc:creator>
      <pubDate>Mon, 13 Oct 2025 00:40:33 +0000</pubDate>
      <link>https://forem.com/abrahambishopcodes/the-mern-stack-tools-i-actually-use-not-just-the-ones-that-look-good-on-twitter-31lo</link>
      <guid>https://forem.com/abrahambishopcodes/the-mern-stack-tools-i-actually-use-not-just-the-ones-that-look-good-on-twitter-31lo</guid>
      <description>&lt;p&gt;Let me be honest: my development setup is not aesthetic.&lt;/p&gt;

&lt;p&gt;I don't have a standing desk with three curved monitors and a mechanical keyboard that sounds like rainfall. My workspace is a laptop, and approximately 47 browser tabs I keep telling myself I'll close "later."&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%2Fxhq5k404wwumnw53l294.gif" 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%2Fxhq5k404wwumnw53l294.gif" alt="gif" width="270" height="480"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;But you know what? My toolkit works. And after three years of building MERN stack projects, I've figured out which tools actually matter.&lt;/p&gt;

&lt;p&gt;Not the trendy ones. The ones that save my sanity when production is on fire.&lt;/p&gt;

&lt;h2&gt;
  
  
  VS Code: The Editor That Doesn't Fight Me
&lt;/h2&gt;

&lt;p&gt;VS Code is my home base. Not because it's perfect (it's definitely crashed during important demos), but because I've finally got it set up exactly how I need it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prettier&lt;/strong&gt; - Because arguing about semicolons is a waste of everyone's time. Hit save, everything formats. Done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ESLint&lt;/strong&gt; - My personal code critic that catches stupid mistakes before they become production problems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitLens&lt;/strong&gt; - Answers the eternal question: "Who wrote this code and what were they thinking?" (Plot twist: it's usually me from three months ago.)&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%2Fbkr5prdy8jbvlrq6h4rz.gif" 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%2Fbkr5prdy8jbvlrq6h4rz.gif" alt="gif" width="480" height="270"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thunder Client&lt;/strong&gt; - For when I need to test an API endpoint but don't want to leave VS Code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tailwind CSS IntelliSense&lt;/strong&gt; - Because remembering whether it's &lt;code&gt;justify-center&lt;/code&gt; or &lt;code&gt;center-justify&lt;/code&gt; shouldn't require a Google search every single time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React code snippets&lt;/strong&gt; - Type &lt;code&gt;rafce&lt;/code&gt;, get a functional component. It's the small things that add up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Import Cost&lt;/strong&gt; - Shows you when you're about to import a 2MB library for one function. Eye-opening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chrome DevTools: Where Bugs Go to Get Caught
&lt;/h2&gt;

&lt;p&gt;Chrome DevTools + React Developer Tools are basically my second home.&lt;/p&gt;

&lt;p&gt;I live in the Network tab when APIs are being weird. The React component tree is a lifesaver when props aren't flowing right. And the Console? That's where I have philosophical conversations with &lt;code&gt;console.log()&lt;/code&gt; about why my variable is undefined.&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%2F9erybepz1q7r7x66syb1.gif" 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%2F9erybepz1q7r7x66syb1.gif" alt="gif" width="500" height="500"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Real talk: if you're not comfortable with DevTools, you're making life harder. I've watched developers waste hours on bugs that would've taken 5 minutes to spot with the Network tab open.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTPie: API Testing Without the Drama
&lt;/h2&gt;

&lt;p&gt;HTTPie is my ride-or-die for API testing.&lt;/p&gt;

&lt;p&gt;Yeah, Postman is popular and powerful. But HTTPie just... works. And it doesn't try to make me sign up for a team workspace when I'm just trying to test a login endpoint at midnight.&lt;/p&gt;

&lt;p&gt;The environment switching between staging and production? Chef's kiss. No more "oops, I just deleted production data because I forgot to switch environments."&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%2Fzq9xun66pbg46k2ehznn.gif" 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%2Fzq9xun66pbg46k2ehznn.gif" alt="gif" width="480" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  MongoDB Compass: When You Just Need to SEE the Data
&lt;/h2&gt;

&lt;p&gt;Sure, typing mongo shell commands makes you feel like a hacker in a movie. But when you need to actually understand your data structure, or figure out why your query returns 0 results when it should return 50, Compass saves the day.&lt;/p&gt;

&lt;p&gt;Visual representation beats staring at JSON in the terminal while your brain tries to parse nested objects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Git + GitHub: Version Control for Adults
&lt;/h2&gt;

&lt;p&gt;Controversial take: I love Git.&lt;/p&gt;

&lt;p&gt;My workflow is boring and that's exactly why it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Feature branches for everything&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Commit often with messages that future me will understand&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pull requests even on solo projects (yes, really)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitHub Issues and Projects keep me organized, which is critical because my brain tries to convince me to start three new features while debugging one thing.&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%2F2n6zg86d9mc1u560k9xz.gif" 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%2F2n6zg86d9mc1u560k9xz.gif" alt="gif" width="480" height="480"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;The real secret? Good commit messages. "Fixed stuff" doesn't help anyone. "Fixed user authentication redirect loop when session expires" helps a LOT three weeks later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Node + Nodemon + Concurrently: The Holy Trinity
&lt;/h2&gt;

&lt;p&gt;Nodemon means I don't have to manually restart my server every time I change one line of code. Which sounds small until you realize you make changes approximately 500 times per hour.&lt;/p&gt;

&lt;p&gt;Concurrently lets me run frontend and backend servers with one command. One terminal, two servers, zero hassle.&lt;/p&gt;

&lt;p&gt;Type &lt;code&gt;npm run dev&lt;/code&gt;, everything starts, you get on with your life. Beautiful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Jest + Supertest: Testing (Yes, Really)
&lt;/h2&gt;

&lt;p&gt;Look, testing isn't fun. Nobody dreams of writing test cases.&lt;/p&gt;

&lt;p&gt;But you know what's REALLY not fun? Deploying on Friday afternoon and having everything break because you changed one function and didn't realize it affected seven other things.&lt;/p&gt;

&lt;p&gt;Jest and Supertest make testing as painless as possible. Write tests for your API endpoints, run them before you push, sleep better at night.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notion: The Second Brain
&lt;/h2&gt;

&lt;p&gt;This is where I keep everything I'll definitely forget.&lt;/p&gt;

&lt;p&gt;Code snippets that solve specific problems. Weird bugs and how I fixed them. Architecture decisions and why I made them.&lt;/p&gt;

&lt;p&gt;It's my external hard drive for developer knowledge. Because there's no way I'm remembering the exact CORS configuration that finally worked.&lt;/p&gt;

&lt;p&gt;I can't count how many times I've thought "I've solved this before" and found the answer in my Notion database in 30 seconds. Plus, the fact that I can access it from anywhere (phone, tablet, borrowed laptop when mine dies) has saved me more times than I'd like to admit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spotify: The Secret Weapon
&lt;/h2&gt;

&lt;p&gt;This isn't about being cool or having the perfect coding playlist. It's about focus.&lt;/p&gt;

&lt;p&gt;Deep focus playlists for complex backend logic. Lo-fi for debugging when my brain hurts. The right audio environment is the difference between flow state and constantly checking Twitter.&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%2Fver6mhiyp7uebulx6nw9.gif" 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%2Fver6mhiyp7uebulx6nw9.gif" alt="gif" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Matters
&lt;/h2&gt;

&lt;p&gt;After years of trying different setups, here's what I've learned:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The best tool is the one you'll actually use.&lt;/strong&gt; That fancy new framework doesn't matter if you spend more time configuring it than building.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Simple beats complicated.&lt;/strong&gt; If your setup requires 45 minutes to explain, it's too complex.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your setup will evolve.&lt;/strong&gt; What works now might not work in a year. That's fine.&lt;/p&gt;

&lt;p&gt;The MERN stack comes with complexity. These tools don't eliminate it, but they make it manageable. They help me ship features instead of fighting with my environment.&lt;/p&gt;

&lt;p&gt;And honestly? That's all I need.&lt;/p&gt;

&lt;p&gt;What tools are essential in YOUR stack? Let's talk in the comments.&lt;/p&gt;

&lt;p&gt;Now if you'll excuse me, I have 47 Chrome tabs to close.&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%2Fb2orjatqermqgmgtpj1q.gif" 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%2Fb2orjatqermqgmgtpj1q.gif" alt="gif" width="500" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Originally published on &lt;a href="https://abraham-bishop.hashnode.dev/" rel="noopener noreferrer"&gt;My Blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>devtools</category>
      <category>devtips</category>
      <category>programming</category>
    </item>
    <item>
      <title>After months of small annoyances and way too much curiosity, I finally made the switch to Linux.

Here's what actually happened (spoiler: I'm not going back).</title>
      <dc:creator>Bishop Abraham</dc:creator>
      <pubDate>Sun, 12 Oct 2025 00:15:28 +0000</pubDate>
      <link>https://forem.com/abrahambishopcodes/after-months-of-small-annoyances-and-way-too-much-curiosity-i-finally-made-the-switch-to-linux-16le</link>
      <guid>https://forem.com/abrahambishopcodes/after-months-of-small-annoyances-and-way-too-much-curiosity-i-finally-made-the-switch-to-linux-16le</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://dev.to/abrahambishopcodes/why-i-finally-ditched-windows-for-linux-and-actually-liked-it-i3f" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgx3h5ek4gbhium9nddck.png" height="auto" class="m-0"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://dev.to/abrahambishopcodes/why-i-finally-ditched-windows-for-linux-and-actually-liked-it-i3f" rel="noopener noreferrer" class="c-link"&gt;
            Why I Finally Ditched Windows for Linux (And Actually Liked It) - DEV Community
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Discover why I switched from Windows to Linux and how it's improved my development workflow, offering control and customization
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png"&gt;
          dev.to
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




</description>
      <category>linux</category>
      <category>windows</category>
      <category>ubuntu</category>
      <category>software</category>
    </item>
    <item>
      <title>Why I Finally Ditched Windows for Linux (And Actually Liked It)</title>
      <dc:creator>Bishop Abraham</dc:creator>
      <pubDate>Sun, 12 Oct 2025 00:14:39 +0000</pubDate>
      <link>https://forem.com/abrahambishopcodes/why-i-finally-ditched-windows-for-linux-and-actually-liked-it-i3f</link>
      <guid>https://forem.com/abrahambishopcodes/why-i-finally-ditched-windows-for-linux-and-actually-liked-it-i3f</guid>
      <description>&lt;p&gt;I've shipped projects on Windows for years. It was familiar, easy, and honestly... it worked.&lt;/p&gt;

&lt;p&gt;Until one day I caught myself rebooting my laptop for the third time that week because Windows Update decided 2 PM on a Tuesday was the perfect time for a forced restart.&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%2Fo73zna9btp7tmv2tlxkw.gif" 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%2Fo73zna9btp7tmv2tlxkw.gif" alt="gif" width="320" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That was my breaking point. After months of small annoyances and way too much curiosity, I finally made the switch to Linux.&lt;/p&gt;

&lt;p&gt;Here's what actually happened (spoiler: I'm not going back).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Stuff That Pushed Me Over the Edge
&lt;/h2&gt;

&lt;p&gt;Look, Windows works. But it started feeling like I was working &lt;em&gt;around&lt;/em&gt; my OS instead of &lt;em&gt;with&lt;/em&gt; it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resource usage was getting ridiculous.&lt;/strong&gt; My laptop has decent specs, but Windows acted like it was running on a potato. Background processes everywhere, random CPU spikes, startup times that made me question my life choices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WSL felt like a band-aid solution.&lt;/strong&gt; Sure, it gave me a Linux terminal... sort of. But it always felt hacky. Like I was trying to fit a square peg into a round hole while Windows watched and judged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I had zero control.&lt;/strong&gt; Want to disable something? Too bad, it's back after the next update.&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%2Fdqh0dm7conoxhsfb9jdd.gif" 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%2Fdqh0dm7conoxhsfb9jdd.gif" alt="gif" width="480" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wasn't chasing the shiny new thing. I just wanted an OS that got out of my way and let me code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making the Jump
&lt;/h2&gt;

&lt;p&gt;I went with &lt;strong&gt;Pop!_OS&lt;/strong&gt; for my first distro. Why? Because I'm not a masochist, and Pop!_OS is basically "Linux for people who want to actually get work done."&lt;/p&gt;

&lt;p&gt;Clean interface, stable, great community, and (this is key) it didn't make me feel like I needed a PhD to install my graphics drivers.&lt;/p&gt;

&lt;p&gt;What changed immediately:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real terminal power.&lt;/strong&gt; No more WSL weirdness. Just a proper Unix environment that does what I tell it to do. Bash scripts actually work. SSH is native. Life is good.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My laptop stopped pretending to be a jet engine.&lt;/strong&gt; Everything feels lighter and faster. I can run multiple Docker containers, dev servers, and VS Code without my fans screaming for mercy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Package management that makes sense.&lt;/strong&gt; Need a tool? &lt;code&gt;sudo apt install whatever&lt;/code&gt;. Done. No hunting for .exe files, no sketchy download sites, no installer wizards that try to bundle McAfee.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blessed silence.&lt;/strong&gt; No "suggested apps." No random popups about Edge. Just my desktop and my work.&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%2Fnvw3497hiam4e3kmm9fp.gif" 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%2Fnvw3497hiam4e3kmm9fp.gif" alt="gif" width="480" height="360"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Got Better
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Docker stopped being a drama queen.&lt;/strong&gt; Containers run natively and fast. No more Docker Desktop eating half my RAM for breakfast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Git just works.&lt;/strong&gt; No weird line ending issues. No path problems. No "Git Bash" as a separate thing. It's all just... there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SSH and networking tools are built-in.&lt;/strong&gt; As someone who enjoys ethical hacking and networking as a hobby, having proper networking tools native to my OS is chef's kiss.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I can customize EVERYTHING.&lt;/strong&gt; Window manager? Changed it. Terminal theme? Exactly how I want it. Keyboard shortcuts? All mine. My dev environment actually feels like MY dev environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Parts That Weren't Great
&lt;/h2&gt;

&lt;p&gt;Real talk: it wasn't all smooth sailing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The learning curve is real.&lt;/strong&gt; If you're used to clicking through everything, get ready to Google stuff. A lot. I spent my first week constantly asking "how do I..." for things that were two clicks on Windows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Some apps just don't exist on Linux.&lt;/strong&gt; Adobe Creative Suite? Nope. Some proprietary dev tools? Sometimes yes, sometimes "here's a workaround." I've found good alternatives for most things, and Wine/VMs handle the rest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hardware can be weird.&lt;/strong&gt; My Bluetooth mouse had a moment. My Wi-Fi drivers needed a chat. Nothing dealbreaking, but expect to do some troubleshooting early on.&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%2F29veprr8burxmy6qp6js.gif" 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%2F29veprr8burxmy6qp6js.gif" alt="gif" width="373" height="480"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;But honestly? Every OS has quirks. At least with Linux, when something breaks, I can actually fix it instead of waiting for Microsoft to maybe address it in six months.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I'm Staying
&lt;/h2&gt;

&lt;p&gt;Linux isn't perfect. No OS is.&lt;/p&gt;

&lt;p&gt;But it fits how I work. It's flexible, powerful, and treats me like an adult who knows what they want to do with their own computer.&lt;/p&gt;

&lt;p&gt;Windows felt like renting. Linux feels like owning.&lt;/p&gt;

&lt;p&gt;If you're a dev who's tired of fighting their OS, curious about having more control, or just want to see what the hype is about, give Linux a shot. Grab Pop!_OS or Linux Mint, throw it on a USB drive, try it out for a weekend.&lt;/p&gt;

&lt;p&gt;Worst case? You learn something new and go back to Windows.&lt;/p&gt;

&lt;p&gt;Best case? You realize your computer can actually be a tool that works FOR you.&lt;/p&gt;

&lt;p&gt;I'm still learning, still tweaking, still Googling random terminal commands. And honestly? That's part of the fun.&lt;/p&gt;

&lt;p&gt;Thinking about making the switch? Got questions? Already on Linux and want to tell me I picked the wrong distro? Let's talk in the comments.&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%2F8qk04x5wh7df15653642.gif" 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%2F8qk04x5wh7df15653642.gif" alt="gif" width="480" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Originally published on &lt;a href="https://abraham-bishop.hashnode.dev/" rel="noopener noreferrer"&gt;My Blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>windows</category>
      <category>ubuntu</category>
      <category>software</category>
    </item>
    <item>
      <title>After building several projects and breaking authentication in creative ways, I finally figured out a setup that actually works and doesn't make me want to throw my laptop out the window.</title>
      <dc:creator>Bishop Abraham</dc:creator>
      <pubDate>Sat, 11 Oct 2025 02:59:25 +0000</pubDate>
      <link>https://forem.com/abrahambishopcodes/after-building-several-projects-and-breaking-authentication-in-creative-ways-i-finally-figured-out-2eca</link>
      <guid>https://forem.com/abrahambishopcodes/after-building-several-projects-and-breaking-authentication-in-creative-ways-i-finally-figured-out-2eca</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://dev.to/abrahambishopcodes/how-i-handle-jwt-authentication-in-expressjs-without-the-headaches-2np3" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu6o9blego4zusjmnelq6.png" height="auto" class="m-0"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://dev.to/abrahambishopcodes/how-i-handle-jwt-authentication-in-expressjs-without-the-headaches-2np3" rel="noopener noreferrer" class="c-link"&gt;
            How I Handle JWT Authentication in Express.js (Without the Headaches) - DEV Community
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            A simple, human explanation of JWT authentication with Node.js, Express, and MongoDB, without losing your mind.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j7kvp660rqzt99zui8e.png"&gt;
          dev.to
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;




</description>
      <category>express</category>
      <category>authentication</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How I Handle JWT Authentication in Express.js (Without the Headaches)</title>
      <dc:creator>Bishop Abraham</dc:creator>
      <pubDate>Sat, 11 Oct 2025 02:56:40 +0000</pubDate>
      <link>https://forem.com/abrahambishopcodes/how-i-handle-jwt-authentication-in-expressjs-without-the-headaches-2np3</link>
      <guid>https://forem.com/abrahambishopcodes/how-i-handle-jwt-authentication-in-expressjs-without-the-headaches-2np3</guid>
      <description>&lt;p&gt;Authentication used to stress me out.&lt;/p&gt;

&lt;p&gt;Not because it's conceptually hard, but because every tutorial I found either oversimplified it to the point of being useless, or made it so complicated I needed a PhD to understand what was happening.&lt;/p&gt;

&lt;p&gt;After building several projects and breaking authentication in creative ways, I finally figured out a setup that actually works and doesn't make me want to throw my laptop out the window.&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%2Fkkk32valoth4pgqrg5ts.gif" 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%2Fkkk32valoth4pgqrg5ts.gif" alt="suprised in a good way" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's how I do it, explained like I'm talking to a friend over coffee, not writing a textbook.&lt;/p&gt;

&lt;h2&gt;
  
  
  What We're Working With
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Node.js &amp;amp; Express&lt;/strong&gt; - The backend&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MongoDB &amp;amp; Mongoose&lt;/strong&gt; - Where user data lives&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;bcryptjs&lt;/strong&gt; - Makes passwords unreadable (important!)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;jsonwebtoken&lt;/strong&gt; - Creates those tokens everyone talks about&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;cookie-parser&lt;/strong&gt; - Handles cookies properly&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;dotenv&lt;/strong&gt; - Keeps secrets actually secret&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nothing fancy. Nothing you can't install in 30 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Letting People Sign Up
&lt;/h2&gt;

&lt;p&gt;When someone registers, we need to save their info. But we can't just store their password as-is. That's like leaving your house key under the doormat with a sign that says "KEY HERE."&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bcryptjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../models/User&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/register&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Turn the password into scrambled nonsense&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hashedPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&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="mi"&gt;10&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;username&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="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hashedPassword&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&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;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User created successfully&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User already exists or invalid input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What's happening: We take their password and scramble it (that's the hashing part). Even if someone breaks into your database, they just see gibberish instead of actual passwords.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The hacker after breaking into your database:&lt;/p&gt;
&lt;/blockquote&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%2Fp29h1x7bndb4vt7okkkp.gif" 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%2Fp29h1x7bndb4vt7okkkp.gif" alt="hacker after breaking into database reaction" width="434" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Logging In and Getting Tokens
&lt;/h2&gt;

&lt;p&gt;This is where it gets interesting. When someone logs in, we give them TWO tokens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Access token&lt;/strong&gt; - Short-lived (15 minutes). Like a temporary pass to get into places.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Refresh token&lt;/strong&gt; - Lasts longer (5 days). Used to get new access tokens without logging in again.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why two? Security. If someone steals your access token, it expires quickly. The refresh token stays safe in a cookie.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;jsonwebtoken&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="n"&gt;generateAccessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;15m&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;app&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/api/login&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Find&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
  &lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&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="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Invalid credentials&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Check&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="n"&gt;matches&lt;/span&gt;
  &lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="n"&gt;isMatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;&lt;span class="n"&gt;isMatch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&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="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Invalid credentials&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Package&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;
  &lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Create&lt;/span&gt; &lt;span class="n"&gt;both&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;
  &lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="n"&gt;refreshToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JWT_REFRESH_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;5d&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="n"&gt;const&lt;/span&gt; &lt;span class="n"&gt;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateAccessToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="n"&gt;Send&lt;/span&gt; &lt;span class="n"&gt;refresh&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;secure&lt;/span&gt; &lt;span class="n"&gt;cookie&lt;/span&gt;
  &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;refreshToken&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;secure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;httpOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;maxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="n"&gt;accessToken&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;What's happening: We check if the user exists, verify their password, then create two tokens. The refresh token goes in a special cookie that JavaScript can't touch (that's the &lt;code&gt;httpOnly&lt;/code&gt; part). The access token goes in the response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Getting a New Access Token
&lt;/h2&gt;

&lt;p&gt;After 15 minutes, your access token expires. Instead of making users log in again, we use the refresh token to get a new one.&lt;/p&gt;

&lt;p&gt;First, set up cookie parsing in your main file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cookieParser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cookie-parser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cookieParser&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create the refresh endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&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="s1"&gt;/token/refresh&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Get the refresh token from the cookie&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;refreshToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Verify it's legit&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;verifiedToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;refreshToken&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;JWT_REFRESH_SECRET&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;verifiedToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Create a new access token&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;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;username&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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;verifiedToken&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;accessToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generateAccessToken&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;username&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;accessToken&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;What's happening: We grab the refresh token from the cookie, check if it's valid, and if it is, we create a fresh access token. Simple.&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%2F0lqde79vsu5sc1nqi0cz.gif" 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%2F0lqde79vsu5sc1nqi0cz.gif" alt="inspecting refresh access token meme" width="480" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Protecting Routes
&lt;/h2&gt;

&lt;p&gt;Now we need to make sure only logged-in users can access certain routes. That's what middleware is for.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authMiddleware&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authHeader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;authHeader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No token provided&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Token comes as "Bearer actualtoken", so we split it&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;authHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;decoded&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&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;JWT_SECRET&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;decoded&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Now we know who's making the request&lt;/span&gt;
    &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;403&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid or expired token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Use it on any route you want to protect&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/profile&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;authMiddleware&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;user&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;User&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;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What's happening: The middleware checks if there's a valid token. If yes, attach the user info to the request and move on. If no, reject them. Think of it as a bouncer checking IDs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Setup Works
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;It's stateless.&lt;/strong&gt; No need to store sessions on the server. Everything lives in the tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It scales.&lt;/strong&gt; Works whether you have 10 users or 10,000.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's secure enough.&lt;/strong&gt; Passwords are hashed, tokens expire, and the refresh token is protected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's not overwhelming.&lt;/strong&gt; You can understand what each piece does without a computer science degree.&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%2F9oh36641i643sbtswaa6.gif" 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%2F9oh36641i643sbtswaa6.gif" alt="simple but honest work" width="480" height="480"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd Add Next
&lt;/h2&gt;

&lt;p&gt;Right now, this handles basic authentication. But for bigger projects, you might want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Role-based access&lt;/strong&gt; - Admins can do more than regular users&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Token blacklisting&lt;/strong&gt; - Invalidate tokens when users log out&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rate limiting&lt;/strong&gt; - Stop people from spamming your login endpoint&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But for most projects? This setup is solid.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Talk
&lt;/h2&gt;

&lt;p&gt;Authentication doesn't have to be scary or complicated. Yes, there are edge cases. Yes, there are more secure ways to do things. But this approach has worked for my projects, and it's simple enough that I can set it up in an hour without pulling my hair out.&lt;/p&gt;

&lt;p&gt;If you're just starting with backend auth or you've been putting it off because it seems overwhelming, start here. Get it working, understand what each part does, then optimize later.&lt;/p&gt;

&lt;p&gt;Perfect is the enemy of shipped.&lt;/p&gt;

&lt;p&gt;Got questions? Different approach? Let me know in the comments. Always happy to learn better ways to do this.&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%2Fe9od0ha4drd7dnehdmvm.gif" 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%2Fe9od0ha4drd7dnehdmvm.gif" alt="Goodbye reaction meme" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Originally published on &lt;a href="https://abraham-bishop.hashnode.dev/" rel="noopener noreferrer"&gt;My Blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>express</category>
      <category>authentication</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
