<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Lucy Love</title>
    <description>The latest articles on Forem by Lucy Love (@mahdava).</description>
    <link>https://forem.com/mahdava</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%2F134942%2F33c78d5d-383a-41a9-8250-27f4db338413.jpeg</url>
      <title>Forem: Lucy Love</title>
      <link>https://forem.com/mahdava</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mahdava"/>
    <language>en</language>
    <item>
      <title>Javascript Symbols</title>
      <dc:creator>Lucy Love</dc:creator>
      <pubDate>Thu, 13 Jun 2024 06:24:30 +0000</pubDate>
      <link>https://forem.com/mahdava/javascript-symbols-80a</link>
      <guid>https://forem.com/mahdava/javascript-symbols-80a</guid>
      <description>&lt;p&gt;The good perk of having a lot of people who code around you is that you end up discussing things that you don't get to see on a day-to-day basis as a simpleton frontend developer.&lt;/p&gt;

&lt;p&gt;This time, I landed on the &lt;strong&gt;concept of symbols in JavaScript&lt;/strong&gt;, which is something I don't have to deal with at work, but something that JavaScript offers and it'd be nice to understand what it is and why it is :D&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Symbol?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A symbol is a unique and immutable data type in JavaScript&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If that doesn't tell you anything (which indeed didn't for me), know that a symbol is one of the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#primitive_values"&gt;JavaScript primitive data types&lt;/a&gt; just as string, boolean, integer etc. but it works like a &lt;em&gt;special identifier to access object properties&lt;/em&gt;, and it can be used more or less like a property key.&lt;/p&gt;

&lt;p&gt;Let's imagine that we have an object where we store a person's &lt;code&gt;name&lt;/code&gt;, an &lt;code&gt;id&lt;/code&gt; and their &lt;code&gt;age&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;person&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="s2"&gt;Sophia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12345678&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// (yes, I'm a trailing comma person)&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to access the value of the &lt;code&gt;id&lt;/code&gt; property, we'd just do:&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="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// will give us 12345678&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is fair to assume that &lt;code&gt;id&lt;/code&gt; won't change as often as the other characteristics of a person, and tailor our work around that assumption.&lt;/p&gt;

&lt;p&gt;Let's try to use a symbol as a key by creating it. This can be done using the &lt;code&gt;Symbol()&lt;/code&gt; constructor:&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;symbolIDKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&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;person&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="s2"&gt;Sophia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;symbolIDKey&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="mi"&gt;12345678&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&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;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;symbolIDKey&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="c1"&gt;// outputs 12345678&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could, in theory, use no &lt;code&gt;"id"&lt;/code&gt; parameter (properly referred as &lt;strong&gt;descriptor&lt;/strong&gt;), but if you were to use more than one symbol key, it'd be more challenging to know which is which.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why symbols then?
&lt;/h2&gt;

&lt;p&gt;Using symbols as object keys will provide you with a unique and guaranteed way of accessing object properties, &lt;strong&gt;even if other code adds or modifies properties with the same key&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example:&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;symbolIDKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&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;person&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="s2"&gt;Sophia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;symbolIDKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12345678&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&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;Some other code, for whatever reason, will try to do&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;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;00000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will be left with&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;symbolIDKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&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;person&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="s2"&gt;Sophia&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;symbolIDKey&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12345678&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;00000000&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;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// will output 00000000&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;person&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;symbolIDKey&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="c1"&gt;// will output our more expected 12345678&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The symbol key is allowing us to preserve the original value even if some other code might try to alter the property &lt;code&gt;id&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;With symbols you can add private properties to an object that are not intended to be modified or accessed directly by other code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But beware! Symbols keys are not enumerated, which means that &lt;strong&gt;they do not show up in the list of keys of the object&lt;/strong&gt; if you try to access them by loops and mappings.&lt;/p&gt;

&lt;p&gt;You cannot even access the symbol keys of an object with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys" rel="norefferer noopener"&gt;&lt;code&gt;keys()&lt;/code&gt;&lt;/a&gt; nor with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames" rel="norefferer noopener"&gt;&lt;code&gt;getOwnPropertyNames()&lt;/code&gt;&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;You will need to be aware of the structure of your object and if you need to access the symbol keys, you'll have to use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols" rel="norefferer noopener"&gt;&lt;code&gt;getOwnPropertySymbols()&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;And that's it! I don't see myself using this approach anytime soon, but it's good to know that, should I be concerned with the integrity of the data I work with, there are ways for me to preserve some information in the flimsy world that JavaScript often creates for us.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and inspiration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://chat.openai.com/"&gt;ChatGPT&lt;/a&gt; prompt: &lt;code&gt;Act like a senior software developer mentor. Explain to me in the simplest way possible what javascript Symbols are, making very basic examples that DO NOT use "foo" "bar" words. Make small sentences and ask me often if I am able to understand. Thank you.&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol"&gt;Symbol&lt;/a&gt; from &lt;a href="https://developer.mozilla.org/en-US/"&gt;mdn web docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://flaviocopes.com/javascript-symbols/"&gt;JavaScript Symbols&lt;/a&gt; from &lt;a href="https://flaviocopes.com/"&gt;Flavio copes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cover: &lt;a href="https://www.freepik.com/free-psd/3d-female-character-reading-book_13678507.htm"&gt;Person sitting on books&lt;/a&gt; and &lt;a href="https://www.freepik.com/free-vector/realistic-3d-shapes-floating-background_13397766.htm"&gt;Background 3d composition&lt;/a&gt; by &lt;a href="https://www.freepik.com/author/freepik"&gt;Freepik&lt;/a&gt;, &lt;a href="https://www.freepik.com/free-psd/website-coding-icon-3d-illustration_28638422.htm"&gt;Cute round interface&lt;/a&gt; by &lt;a href="https://www.freepik.com/author/ekayasadesign"&gt;Ekayasa.Design&lt;/a&gt;

Originally posted in &lt;a href="https://oh-no.ooo"&gt;oh-no.ooo&lt;/a&gt; (&lt;a href="https://www.oh-no.ooo/articles/javascript-symbols"&gt;JavaScript Symbols&lt;/a&gt;), my personal website.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>learning</category>
      <category>coding</category>
    </item>
    <item>
      <title>An Introduction to Quantum Computing</title>
      <dc:creator>Lucy Love</dc:creator>
      <pubDate>Tue, 11 Jun 2024 11:41:49 +0000</pubDate>
      <link>https://forem.com/mahdava/an-introduction-to-quantum-computing-23k</link>
      <guid>https://forem.com/mahdava/an-introduction-to-quantum-computing-23k</guid>
      <description>&lt;p&gt;Quantum computing here, quantum computing there, quantum computing everywhere! Can we make some sense out of it? I'd like to not feel like completely out of place when people talk about it, so let's figure it out together!&lt;/p&gt;

&lt;blockquote&gt;
I start this serie of posts about Quantum computing &lt;strong&gt;for personal learning&lt;/strong&gt;, with the sake of understanding the general implications of it in our modern society and how it can impact my day-to-day life with technology. I do not claim to be an expert in the topic and this are more my notes based on what I'm learning reading articles and asking ChatGPT to simplify what I'm reading :D&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;Quantum computing&lt;/strong&gt; is a revolutionary new technology that harnesses the principles of &lt;strong&gt;quantum mechanics&lt;/strong&gt; (an intricate branch of physics that explores the wonders of the subatomic realm and tries to explain the nature of particles to discover the fundamental principles that govern our world -- we're not here today for this though) to process information at incredible speeds.&lt;/p&gt;

&lt;p&gt;Unlike classical computers, which store and process information using bits that are either 0 or 1, quantum computers use quantum bits, or &lt;strong&gt;qubits&lt;/strong&gt;, which can exist in multiple states simultaneously, meaning that a qubit can be both 0 and 1. ...but how?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2FdavATh6goeQ9CIcuMx1UZ%2F4aa0b207e039d24629eda7ad547d3b17%2Fqubit.svg%3Fr%3D50" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2FdavATh6goeQ9CIcuMx1UZ%2F4aa0b207e039d24629eda7ad547d3b17%2Fqubit.svg%3Fr%3D50" alt="Representation of a qubit compared to a typical bit."&gt;&lt;/a&gt;Representation of a qubit compared to a typical bit.&lt;br&gt; &lt;em&gt;Source: &lt;a href="https://devopedia.org/qubit" rel="noopener noreferrer"&gt;Devopedia&lt;/a&gt;&lt;/em&gt;. &lt;em&gt;Credit: &lt;a href="https://www.volkswagenag.com/en/news/stories/2019/11/where-is-the-electron-and-how-many-of-them.html" rel="noopener noreferrer"&gt;Volkswagen Aktiengesellschaft 2019&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Superposition
&lt;/h2&gt;

&lt;p&gt;Let's talk about the idea of &lt;strong&gt;superposition&lt;/strong&gt;, which describes &lt;strong&gt;the ability of a qubit to exist in multiple states at the same time&lt;/strong&gt;. If a normal bit can have as a state either &lt;code&gt;0&lt;/code&gt; or &lt;code&gt;1&lt;/code&gt;, the state of qubit can be represented as&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="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;ψ&lt;/span&gt;&lt;span class="err"&gt;⟩&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;α&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="err"&gt;⟩&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;β&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;⟩&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which would require quite some explantation, but to make it briefly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The symbol &lt;code&gt;|ψ⟩&lt;/code&gt; represents the state of the qubit. &lt;code&gt;ψ&lt;/code&gt; is just a variable name, and the &lt;code&gt;|⟩&lt;/code&gt; symbols are like brackets that indicate it's a quantum state. &lt;/li&gt;
&lt;li&gt;The &lt;code&gt;α|0⟩&lt;/code&gt; and &lt;code&gt;β|1⟩&lt;/code&gt; terms are &lt;strong&gt;probability amplitudes&lt;/strong&gt;. They represent the chances of finding the qubit in the states &lt;code&gt;|0⟩&lt;/code&gt; and &lt;code&gt;|1⟩&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;α&lt;/code&gt; represents the probability amplitude of finding the qubit in the &lt;code&gt;|0⟩&lt;/code&gt; state;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;β&lt;/code&gt; represents the probability amplitude of finding the qubit in the &lt;code&gt;|1⟩&lt;/code&gt; state.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(... and yes because I also had to ask myself, probability amplitudes are quite complex numbers, but the gist of them is that the sum of α and β adds up to 1, meaning that the sum of the probabilities of all possible outcomes is always equal to 1.)&lt;/p&gt;

&lt;p&gt;We can picture the state of a qubit like a point on a ball, called the &lt;strong&gt;Bloch sphere&lt;/strong&gt;. The numbers α and β decide where exactly on the ball the qubit's point is. If α and β are regular numbers, then the qubit's point is on the middle of the ball's surface, like the equator. This means the qubit is equally a mix of &lt;code&gt;|0⟩&lt;/code&gt; and &lt;code&gt;|1⟩&lt;/code&gt;. But if α and β are complex numbers (&lt;a href="https://www.mathsisfun.com/numbers/complex-numbers.html" rel="noopener noreferrer"&gt;read more about complex numbers on Math Is Fun&lt;/a&gt;), the qubit's point is somewhere else on the ball's surface. This means the qubit is a more general mix of &lt;code&gt;|0⟩&lt;/code&gt; and &lt;code&gt;|1⟩&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When a qubit is in superposition, it is like it's exploring all possible states at once. However, &lt;strong&gt;when we measure the qubit, it &lt;em&gt;collapses&lt;/em&gt; into a definite state&lt;/strong&gt;, either 0 or 1. The act of measurement forces the qubit to choose one of the possibilities, and from that point on, it behaves like a classical bit.&lt;/p&gt;

&lt;p&gt;For instance, if &lt;code&gt;|α|^2 = 0.4&lt;/code&gt; and &lt;code&gt;|β|^2 = 0.6&lt;/code&gt;, the measurement is more likely to yield the outcome 1, but there is still a chance of obtaining the outcome 0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Okay but... how do you set a qubit in superposition?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In order to do that, we can use a specific &lt;strong&gt;quantum gate&lt;/strong&gt; known as the &lt;strong&gt;Hadamard gate (H gate)&lt;/strong&gt; (more about what is a quantum gate later :D). The Hadamard gate creates an equal superposition of the &lt;code&gt;|0⟩&lt;/code&gt; and &lt;code&gt;|1⟩&lt;/code&gt; states for a qubit. Here's a simplified explanation of how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start with a qubit in the &lt;code&gt;|0⟩&lt;/code&gt; state or the &lt;code&gt;|1⟩&lt;/code&gt; state&lt;/li&gt;
&lt;li&gt;Apply the Hadamard gate (&lt;code&gt;H&lt;/code&gt; gate) to the qubit&lt;/li&gt;
&lt;li&gt;If the qubit is initially in the &lt;code&gt;|0⟩&lt;/code&gt; state, the H gate will put it into an equal superposition of &lt;code&gt;|0⟩&lt;/code&gt; and &lt;code&gt;|1⟩&lt;/code&gt;. The resulting state will be &lt;code&gt;(|0⟩ + |1⟩) / √2&lt;/code&gt;, meaning the qubit is in both states simultaneously&lt;/li&gt;
&lt;li&gt;But, if the qubit is initially in the &lt;code&gt;|1⟩&lt;/code&gt; state, the H gate will again put it into an equal superposition of &lt;code&gt;|0⟩&lt;/code&gt; and &lt;code&gt;|1⟩&lt;/code&gt; but the resulting state will be &lt;code&gt;(|0⟩ - |1⟩) / √2&lt;/code&gt;, meaning the qubit is in both states but with a phase shift (which is a far more intricate topic and I am still looking to find good and simple readings about it -- feel free to share in the comment section below!).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Reading the values of multiple qubits works similarly, with each qubit measured individually, and the outcomes combined to form a classical bit string or &lt;strong&gt;a quantum state in the case of entanglement&lt;/strong&gt;. Which leads us to the next point...&lt;/p&gt;

&lt;h2&gt;
  
  
  Entanglement
&lt;/h2&gt;

&lt;p&gt;Another important concept in quantum computing is &lt;strong&gt;entanglement&lt;/strong&gt;, which describes the phenomenon of &lt;strong&gt;two or more qubits being connected in a way that allows them to affect each other's behavior&lt;/strong&gt;, even if they are separated by large distances. Fundamentally, entanglement creates instantaneous correlations between their measurement outcomes, taking place in three stages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Preparation&lt;/strong&gt;: two or more qubits are brought together and interact with each other in a specific way &lt;strong&gt;through a quantum gate operation&lt;/strong&gt; (too long of a topic to cover here for now, but &lt;a href="https://medium.com/@universalquantum/quantum-gates-explained-without-the-maths-1c40e7d79611" rel="noopener noreferrer"&gt;Universal Quantum has a great article on Medium about quantum gates&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resulting State&lt;/strong&gt;: as a result of this interaction, the qubits become entangled and share a &lt;strong&gt;joint quantum state&lt;/strong&gt;, which cannot be expressed as a simple combination of individual qubit states as &lt;strong&gt;the  entangled state encompasses the entire system as a whole rather than describing each qubit independently&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Correlations&lt;/strong&gt;: the measurement outcomes of one qubit are instantaneously correlated with the measurement outcomes of the other(s). &lt;strong&gt;These correlations hold true regardless of the physical separation between the entangled qubits&lt;/strong&gt;, which is often referred to as &lt;em&gt;non-locality&lt;/em&gt; or &lt;em&gt;spooky action at a distance&lt;/em&gt; (once again, a topic for another time). &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Briefly about Quantum gates
&lt;/h2&gt;

&lt;p&gt;This is where I start to lose it a bit after the Hadamard gate we mentioned before. Sounds like a good place where I should continue reading more until I am confident enough to write notes about the topic 😎 Anyway...&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A quantum gate is an instruction (or operation) that we can use to change the state of qubits&lt;/strong&gt;. Just like how math operations such as addition or multiplication transforms numbers, a quantum gate transforms the quantum state of qubits, each gate having a specific effect on the qubits: rotating the state, flipping it, or putting it in a superposition and whatsoever.&lt;/p&gt;

&lt;p&gt;Basically, they are the building blocks that help us manipulate and utilize the power of quantum computing. Once again, &lt;a href="https://medium.com/@universalquantum/quantum-gates-explained-without-the-maths-1c40e7d79611" rel="noopener noreferrer"&gt;Universal Quantum has a great article on Medium about quantum gates&lt;/a&gt; and I recommend checking something more by yourself (and if you feel generous, don't be afraid to share some good links with me :D)&lt;/p&gt;

&lt;h2&gt;
  
  
  Briefly about Challenges
&lt;/h2&gt;

&lt;p&gt;Seems fair to mention, before closing, why this technology is not yet widespread and what are the things that it needs to overcome.&lt;/p&gt;

&lt;p&gt;One of the major challenges in building a quantum computer is the delicate nature of qubits. Because they are based on the principles of quantum mechanics, &lt;strong&gt;qubits are easily affected by their environment&lt;/strong&gt;, and can be easily disrupted by outside factors such as temperature, noise, or even light. This makes it difficult to control and manipulate qubits, and to maintain their quantum state for long periods of time.&lt;/p&gt;

&lt;p&gt;Despite these challenges, researchers have made significant progress in developing quantum computers in recent years. In 2019, &lt;a href="https://ai.googleblog.com/2019/10/quantum-supremacy-using-programmable.html" rel="noopener noreferrer"&gt;Google announced that its quantum computer had achieved "quantum supremacy"&lt;/a&gt; by solving a problem that would be impossible for a classical computer to solve in a reasonable amount of time. This was a major milestone in the development of quantum computing, and showed that the technology is rapidly advancing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;So, what did we learn here?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We've learned about &lt;strong&gt;qubits&lt;/strong&gt;, which unlike the binary bits in classical computing, can exist in multiple states at once due to &lt;strong&gt;superposition&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;We've also discovered that a specific quantum gate, the &lt;strong&gt;Hadamard gate&lt;/strong&gt;, can set a qubit in this superposition state.&lt;/li&gt;
&lt;li&gt;Furthermore, qubits can be &lt;strong&gt;entangled&lt;/strong&gt;, meaning they can affect each other instantaneously irrespective of the distance between them.&lt;/li&gt;
&lt;li&gt;Lastly, we've had a general discussion about &lt;strong&gt;quantum gates&lt;/strong&gt;, the operations that manipulate the state of qubits, serving as the foundational building blocks of quantum computing.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;I'd love to continue my studies focusing more on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(First of all, brushing up my linear algebra, because it seems to help a lot reading documents online)&lt;/li&gt;
&lt;li&gt;Quantum gates&lt;/li&gt;
&lt;li&gt;Quantum algorithms &lt;/li&gt;
&lt;li&gt;Quantum error correction &lt;/li&gt;
&lt;li&gt;More about quantum supremacy&lt;/li&gt;
&lt;li&gt;More about challenges&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you for reading so far, if you did, and don't hesitate sharing good resources in the comments below if you feel like!&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and inspiration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://devopedia.org/qubit" rel="noopener noreferrer"&gt;Qubit&lt;/a&gt; from &lt;a href="https://devopedia.org" rel="noopener noreferrer"&gt;Devopedia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://quantum.country/qcvc" rel="noopener noreferrer"&gt;Quantum Computing for the Very Curious&lt;/a&gt; from Andy Matuschak and Michael Nielsen on &lt;a href="https://quantum.country" rel="noopener noreferrer"&gt;Quantum Country&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Quantum_computing" rel="noopener noreferrer"&gt;Quantum computing&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Quantum_superposition" rel="noopener noreferrer"&gt;Quantum superposition&lt;/a&gt; &amp;amp; &lt;a href="https://en.wikipedia.org/wiki/Quantum_entanglement" rel="noopener noreferrer"&gt;Quantum entanglement&lt;/a&gt; from &lt;a href="https://en.wikipedia.org" rel="noopener noreferrer"&gt;Wikipedia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ai.googleblog.com/2019/10/quantum-supremacy-using-programmable.html" rel="noopener noreferrer"&gt;Quantum Supremacy Using a Programmable Superconducting Processor&lt;/a&gt; from John Martinis (Chief Scientist Quantum Hardware) and Sergio Boixo( Chief Scientist Quantum Computing Theory) at Google AI Quantum via &lt;a href="https://ai.googleblog.com/" rel="noopener noreferrer"&gt;Google Research&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=OWJCfOvochA" rel="noopener noreferrer"&gt;Quantum Computing Expert Explains One Concept in 5 Levels of Difficulty&lt;/a&gt; with Dr. Talia Gershon (Senior Manager, Quantum Research at IBM) from &lt;a href="https://www.wired.com/" rel="noopener noreferrer"&gt;Wired&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://chat.openai.com/" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt; prompts:
&lt;code&gt;How can a quantum bit be both 0 and 1 at the same time? Can you give me an accurate yet simple description to follow?&lt;/code&gt;
&lt;code&gt;How do we read the values of qubits?&lt;/code&gt;
&lt;code&gt;Can you explain to me in simple terms what is qubits entanglement, how does it happen, and what does it imply?&lt;/code&gt;
&lt;code&gt;Can you tell me more about the correlation in entanglement?&lt;/code&gt;
&lt;code&gt;Can you explain to me in simple terms what is qubits entanglement, how does it happen, and what does it imply?Can you tell me more about the resulting state of entanglement?&lt;/code&gt;
... and honestly too many more to share xD&lt;/li&gt;
&lt;li&gt;Cover: &lt;a href="https://www.freepik.com/free-psd/3d-characters-business-fall-illustration_26314271.htm" rel="noopener noreferrer"&gt;3d characters business fall illustration&lt;/a&gt;, &lt;a href="https://www.freepik.com/free-psd/3d-rendering-back-school-icon_30118660.htm" rel="noopener noreferrer"&gt;3D Atom&lt;/a&gt; and &lt;a href="https://www.freepik.com/free-vector/realistic-3d-shapes-floating-background_13397766.htm" rel="noopener noreferrer"&gt;Background 3D composition&lt;/a&gt; by &lt;a href="https://www.freepik.com/author/freepik" rel="noopener noreferrer"&gt;Freepik&lt;/a&gt;; Blurred &lt;a href="https://unsplash.com/photos/rCbdp8VCYhQ" rel="noopener noreferrer"&gt;starry sky&lt;/a&gt; by &lt;a href="https://unsplash.com/@andyjh07" rel="noopener noreferrer"&gt;Andy Holmes&lt;/a&gt; via &lt;a href="https://unsplash.com/" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;a&gt;&lt;/a&gt;

Originally posted in &lt;a href="https://oh-no.ooo" rel="noopener noreferrer"&gt;oh-no.ooo&lt;/a&gt; (&lt;a href="https://www.oh-no.ooo/articles/an-introduction-to-quantum-computing" rel="noopener noreferrer"&gt;An Introduction to Quantum Computing&lt;/a&gt;), my personal website.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>quantum</category>
      <category>superposition</category>
      <category>entanglement</category>
      <category>programming</category>
    </item>
    <item>
      <title>Generics in Typescript and how to use them</title>
      <dc:creator>Lucy Love</dc:creator>
      <pubDate>Mon, 10 Jun 2024 20:13:24 +0000</pubDate>
      <link>https://forem.com/mahdava/generics-in-typescript-and-how-to-use-them-3i9</link>
      <guid>https://forem.com/mahdava/generics-in-typescript-and-how-to-use-them-3i9</guid>
      <description>&lt;p&gt;Sometimes I wonder whether I love or hate Typescript. I see the benefits of implementing it in the majority of frontend solutions, but I struggle with the syntax and the mumbo jumbo names that don't tell me anything. "Generics" would be one of those, as the name kindly suggests too, it's a name that could mean anything 🤷 When I find myself in the situation where I think I have grasped something but I haven't quite, the best solution is to try to write something about it to bring in clarity!&lt;/p&gt;

&lt;h2&gt;
  
  
  So what are Generics?
&lt;/h2&gt;

&lt;p&gt;Generics in TypeScript provide a way to create reusable data structures (arrays, stacks, queues, linked lists etc.), components and functions that can work with different data types.&lt;/p&gt;

&lt;p&gt;Take for example:&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Dictionary&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="na"&gt;key&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;T&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;With generics you can create a container type that can hold different types of values based on needs, e.g.:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myDictionary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dictionary&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;180&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myOtherDictionary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dictionary&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="o"&gt;&amp;gt;&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;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;New York&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;This is useful when you want to create a &lt;strong&gt;flexible and type-safe container&lt;/strong&gt;, such as a dictionary or a set. You'll be guaranteed, whether the structure will accommodate strings or numbers, that it will follow the interface &lt;code&gt;Dictionary&lt;/code&gt; and expect an object with keys whose value will reflect the data you use it with (=== if you have &lt;code&gt;Dictionary&amp;lt;string&amp;gt;&lt;/code&gt; the values of the keys can only be &lt;code&gt;string&lt;/code&gt;, if you have &lt;code&gt;Dictionary&amp;lt;number&amp;gt;&lt;/code&gt; the values of the keys can only be &lt;code&gt;number&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Let's make another practical example; let's say you want to have a function that allows you to print whatever type of array in a particular format, like an ordered list. In this case, &lt;strong&gt;the type of the data passed is not relevant to you&lt;/strong&gt;, you only care that it's presented in an ordered list.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;printArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/li&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&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="s2"&gt;`&amp;lt;ol&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/ol&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;Now you can use this function to format the arrays before appending them to a div:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;printArray&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;array&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
    &lt;span class="nx"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;li&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/li&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&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="s2"&gt;`&amp;lt;ol&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/ol&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// An example function to append HTML content to a div element&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;appendToDiv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;containerId&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;content&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="k"&gt;void&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;container&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="nx"&gt;containerId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Our data types&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbers&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="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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&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;strings&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="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apple&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;banana&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;orange&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Our data types formatted through the printArray function&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbersListHTML&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;printArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numbers&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;stringsListHTML&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;printArray&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;strings&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Append the lists to an hypotetical div container&lt;/span&gt;
&lt;span class="c1"&gt;// that shows the list&lt;/span&gt;
&lt;span class="nf"&gt;appendToDiv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;orderedLists&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;numbersListHTML&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;appendToDiv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;orderedLists&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stringsListHTML&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example, &lt;code&gt;printArray&lt;/code&gt; doesn't care whether the array inputted is a numeric or a string one, but it makes sure to guarantee type safety based on the data type you pass to it.&lt;/p&gt;

&lt;p&gt;Not bad, right?&lt;/p&gt;




&lt;h2&gt;
  
  
  What is a somewhat more practical application of generics in the real-life coding world?
&lt;/h2&gt;

&lt;p&gt;Generics can be useful when working with promises and asynchronous operations, allowing you to specify the type of the resolved value.&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;// Function that returns a promise to fetch data from an API&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="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="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;Network response was not ok&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;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;error&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;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;Error fetching data:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Usage&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;UserData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/users/1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserData&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;apiUrl&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;data&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;// Here, 'data' will be of type UserData&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User Data:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="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;error&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;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;Error fetching user data:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&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;While this example is not perfect, it offers us a great way to dynamically query for various URLs, and for each case we have the possibility to provide the type we expect to receive: we query for &lt;code&gt;https://api.example.com/users/1&lt;/code&gt; - we expect to receive a response containing user information - so we provide the interface &lt;code&gt;UserData&lt;/code&gt; to the function &lt;code&gt;fetchData&amp;lt;UserData&amp;gt;(apiUrl)&lt;/code&gt; and if the request doesn't fail, our response will be already using the correct interface. Neat!&lt;/p&gt;



&lt;h2&gt;
  
  
  Challenges with Generics
&lt;/h2&gt;

&lt;p&gt;Not all that shines is gold, and the same can be said about generics. While they offer this &lt;strong&gt;great versatility&lt;/strong&gt;, you can imagine &lt;strong&gt;they also provide a lot of complexity to a codebase&lt;/strong&gt;, as they will require developers to pay better attention to the data flow and make sure that things won't go as unexpected.&lt;/p&gt;

&lt;p&gt;Together with the broader learning curve proposed to developers, there are also various limitations of type inferring that might make generics limiting to a practical application. No idea about those limits, will let you know when I stumble on those :D &lt;/p&gt;

&lt;h2&gt;
  
  
  Long story short
&lt;/h2&gt;

&lt;p&gt;If you use them, make sure it makes sense on why you're using them and that they actually bring benefits on what you're doing. &lt;strong&gt;If you're working on a npm package that needs to accommodate different solutions&lt;/strong&gt; (idk, a table with columns that can sort according to the data type provided, where you might not know ahead of time what values will be entered), &lt;strong&gt;generics might be very well what you're looking for&lt;/strong&gt;! Bear in mind however, that they will always create an extra layer of complexity that you need to account for your code and for all your team mates!&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and inspiration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Various prompts from ChatGPT&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/2/generics.html"&gt;TypeScript Generics Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-use-generics-in-typescript"&gt;How to use Generics in TypeScript&lt;/a&gt; by &lt;a href="https://www.digitalocean.com/community/users/jonathancardoso"&gt;Jonathan Cardoso&lt;/a&gt; via &lt;a href="https://www.digitalocean.com/"&gt;Digital Ocean&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cover: &lt;a href="https://www.freepik.com/free-psd/concept-mobile-application-cloud-services-male-character-sits-big-cloud-sign-with-phone-3d-illustration_26314276.htm"&gt;Concept mobile application and cloud services character&lt;/a&gt; by &lt;a href="https://www.freepik.com"&gt;Freepik&lt;/a&gt;, &lt;a href="https://www.freepik.com/free-vector/realistic-white-monochrome-background_16223330.htm"&gt;Realistic white monochrome background&lt;/a&gt; by &lt;a href="https://www.freepik.com"&gt;Freepik&lt;/a&gt;

Originally posted in &lt;a href="https://oh-no.ooo"&gt;oh-no.ooo&lt;/a&gt; (&lt;a href="https://www.oh-no.ooo/articles/generics-in-typescript-and-how-to-use-them"&gt;Generics in Typescript and how to use them&lt;/a&gt;), my personal website.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>learning</category>
    </item>
    <item>
      <title>declare-ai.org - ... so, who wrote that?!</title>
      <dc:creator>Lucy Love</dc:creator>
      <pubDate>Mon, 10 Jun 2024 11:45:58 +0000</pubDate>
      <link>https://forem.com/mahdava/declare-aiorg-so-who-wrote-that-3d35</link>
      <guid>https://forem.com/mahdava/declare-aiorg-so-who-wrote-that-3d35</guid>
      <description>&lt;p&gt;One of the latest interesting discussions on Slack at work has been about the value proposition of &lt;a href="https://declare-ai.org"&gt;declare-ai.org&lt;/a&gt;, a website created (&lt;em&gt;without any assistance from a Generative AI&lt;/em&gt;) by &lt;a href="https://naildrivin5.com/bio/index.html"&gt;David Bryant Copeland&lt;/a&gt; that recognises the excitement around AI and wants to help people inform and be informed about its uses.&lt;/p&gt;

&lt;p&gt;(bit off topic but, I am perplexed by the fact that David's own website doesn't have any comment about AI Content Declaration; perhaps they felt they had said all about the topic in the main website. Or perhaps they just wanted to make sure it is clear to people that their work has nothing to do with any sort of AI, maybe out of frustration for the new wave of low-quality/low-effort content blatantly created with AI and not wanting their work even remotely put on the same plate)&lt;span title="shrugging"&gt;🤷&lt;/span&gt;.&lt;/p&gt;

&lt;p&gt;While I recommend checking the website (as I couldn't write any better about it than you could deduct from checking the actual site), the process it proposes is as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7hd7z1zztkojyxaygk7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg7hd7z1zztkojyxaygk7.png" alt="Flow proposed by AI Content Declaration on how to determine what type of Generative AI attribution you need for your content." width="800" height="734"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Flow proposed by AI Content Declaration on how to determine what type of Generative AI attribution you need for your content. Diagram generated with &lt;a href="https://venngage.com/"&gt;Venngage&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;Not sure if the diagram can be read in an accessible way, therefore let me repeat it here (I will use a structure that proposes first the condition that end the flow). We start asking ourselves &lt;strong&gt;Was Generative AI used in any way?&lt;/strong&gt;; if the answer is no, then the answer is &lt;strong&gt;None&lt;/strong&gt; (as in no contribution from generative AI). If the answer is yes, we are prompted to another question &lt;strong&gt;Did Generative AI produce the entire work?&lt;/strong&gt;; answering yes will land us on &lt;strong&gt;Total&lt;/strong&gt;, as in total AI contribution; if we answer no, we are asked the last question &lt;strong&gt;Did Generative AI contribute creatively?&lt;/strong&gt;; yes brings us to &lt;strong&gt;Creative Assistance&lt;/strong&gt; and no will bring us to &lt;strong&gt;Non-creative Assistance&lt;/strong&gt;.&lt;/blockquote&gt;

&lt;p&gt;It is up to your own judgement to determine if you used the AI in a creative way, but &lt;a href="https://declare-ai.org/1.0.0/assess.html#creative-contribution"&gt;the website offers you a nice way to determine what could be considered creative assistance and what not&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And once you go through this hierarchy, &lt;a href="https://declare-ai.org/1.0.0/declare.html"&gt;you can make a public declaration about it&lt;/a&gt;, in the best way that suits you and with the examples proposed. It allegedly also proposes to add this information in the form of meta tags... because why not?!&lt;/p&gt;

&lt;p&gt;Now now, will I use it? &lt;em&gt;Not yet&lt;/em&gt;! I would like to see it having more popularity; but what I like to do is to be open about the source of my work! And that's why &lt;strong&gt;I gladly mention at least the most important prompts I ask about to ChatGPT&lt;/strong&gt; at the end of each article. My go-to way to use ChatGPT is to get inspiration on how to start discussing about a topic, steal good-sounding adjectives (as my English can only benefit from expanding my vocabulary), and in general to get over a writer's block that often prevents me from sharing more, and learn more about something.&lt;/p&gt;

&lt;p&gt;More than often, I read what ChatGPT proposes to me, and I'm immediately like &lt;em&gt;nope, definitely not that!&lt;/em&gt; as it often goes with a very bland structure, lots of repetition, and unneeded conclusion paragraphs that give no particular value to the topic asked. But more than once, when I want to make sure I understand something about a particular topic, &lt;strong&gt;it performs as a great teacher that never gets tired&lt;/strong&gt;, no matter how &lt;em&gt;stupider&lt;/em&gt; my questions become. And it's really a teacher that I'd wish for everyone to have.&lt;/p&gt;

&lt;p&gt;Many feel ashamed to mention they'd use any sort of generative AI and they'd prefer to keep it hidden. Instead of having a sense of appreciation for this technology, &lt;strong&gt;a lot of people tend to judge negatively the skills of people using AI&lt;/strong&gt;, assuming that they're lazy, not knowledgeable, not actual professionals and that they'd not be able to succeed without such tool. I personally find unfair to question people's skills' worth based on how much they like to use AI, as I don't think my critical thinking is compromised any more than it'd be if I were to acquire information from a YouTube video, an online article, a book and so on. With that premise, I use ChatGPT as &lt;strong&gt;one among many sources&lt;/strong&gt; to acquire knowledge and understanding of a topic, and &lt;strong&gt;it never is&lt;/strong&gt; for me &lt;strong&gt;the only source of information&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Rather than hide its usage, &lt;strong&gt;I absolutely love the idea to share with people how it helps me go past a lot of hurdles&lt;/strong&gt;. Before ChatGPT, I also have never been particularly shy about sharing where I've learned something, or what sources I have browsed to learn and/or do something. I really love to share with people because I would not be the person that I am today if people didn't share the things I've digested to this day.&lt;/p&gt;

&lt;p&gt;We seem to forget that not too long ago, we were all assuming &lt;strong&gt;developers were just copying stuff from StackOverflow&lt;/strong&gt; and asking questions over there. So how does that exactly differ, in terms of originality and competence, from what ChatGPT offers us these days?&lt;/p&gt;




&lt;p&gt;Have you ever wondered how many people make use of ChatGPT for writing their blog posts? What's your take on the topic? &lt;strong&gt;Should people be more clear to which extend they use AI or would you just be happy to have valuable content in front of your eyes, regardless of how it came to be?&lt;/strong&gt; Let me hear your opinion in the comments!&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and inspiration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://declare-ai.org/"&gt;Declare-AI official website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The aforementioned discussion on Slack at work&lt;/li&gt;
&lt;li&gt;Cover: Title and background gradient tweaked out with the DOM Inspector from &lt;a href="https://declare-ai.org/"&gt;Declare-AI official website&lt;/a&gt;

Originally posted in &lt;a href="https://oh-no.ooo"&gt;oh-no.ooo&lt;/a&gt; (&lt;a href="https://www.oh-no.ooo/snippets/declare-ai-org-so-who-wrote-that"&gt;declare-ai.org - ... so, who wrote that?!&lt;/a&gt;), my personal website.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>chatgpt</category>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Solving Tailwind's "Unknown at rule @apply"</title>
      <dc:creator>Lucy Love</dc:creator>
      <pubDate>Sun, 09 Jun 2024 20:33:11 +0000</pubDate>
      <link>https://forem.com/mahdava/solving-tailwinds-unknown-at-rule-apply-3c7g</link>
      <guid>https://forem.com/mahdava/solving-tailwinds-unknown-at-rule-apply-3c7g</guid>
      <description>&lt;p&gt;Chances are you are using VSCode, and chances are you're also using Tailwind in one of your projects. Chances are that at my first &lt;em&gt;chances are...&lt;/em&gt; you went immediately &lt;em&gt;nuh-uh&lt;/em&gt; and moved on (and if you're a NeoVim user I can't help you anyway, you're already doomed and lost in the recommended plugins someone chose for you and you're probably still figuring out half of them) but if I got your attention with the first two assumptions, then this post might be relevant for you!&lt;/p&gt;

&lt;p&gt;One issue I've been having ever since using Tailwind with SCSS modules has been that VSCode goes absolutely ballistic marking every &lt;code&gt;@apply&lt;/code&gt; as an unknown CSS rule, &lt;strong&gt;as the editor assumes it's one &lt;code&gt;at-rule&lt;/code&gt;&lt;/strong&gt; from CSS. (If you are wondering what at-rules are, &lt;code&gt;@import&lt;/code&gt; and &lt;code&gt;@media&lt;/code&gt; might sound a bit more familiar :D)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@apply&lt;/code&gt; is a Tailwind directive that mimics in semantics a native CSS at-rule, and this one in the specific takes care of enabling Tailwind utility classes in a .scss file ... which by now we already now — &lt;em&gt;I know, we wouldn't be reading this article otherwise&lt;/em&gt; — so jumping to the main thing, let me present you my favourite solution from &lt;a href="https://byby.dev/at-rule-tailwind"&gt;the solutions list that this article from byby.dev&lt;/a&gt; proposes.&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;.vscode&lt;/code&gt; folder in your project, create a &lt;code&gt;tailwind_directives.json&lt;/code&gt; file and add the following lines. I took the liberty of expanding from the article, which was talking specifically about the &lt;code&gt;@tailwind&lt;/code&gt; directive, and take it as a chance to put &lt;a href="https://tailwindcss.com/docs/functions-and-directives"&gt;all the Tailwind specific directives I could find from Tailwind's documentation&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"atDirectives"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@tailwind"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use the @tailwind directive to insert Tailwind's `base`, `components`, `utilities`, and `screens` styles into your CSS."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@apply"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use @apply to inline any existing utility classes into your own custom CSS."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@screen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The screen function allows you to create media queries that reference your breakpoints by name instead of duplicating their values in your own CSS. Apparently deprecated in favour of @media?!"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@layer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use the @layer directive to tell Tailwind which “bucket” a set of custom styles belong to. Valid layers are base, components, and utilities."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@config"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Use the @config directive to specify which config file Tailwind should use when compiling that CSS file. Do not put @config before your @import statements."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, head to &lt;code&gt;settings.json&lt;/code&gt; and add these two lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;other&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;stuff&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"css.customData"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;".vscode/tailwind_fix.json"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scss.customData"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;".vscode/tailwind_fix.json"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And voilá! Done!&lt;br&gt;
&lt;/p&gt;

&lt;br&gt;
...&lt;br&gt;
Now now, you might be tempted to follow the first solution proposed by the article, which simply tells VSCode to ignore every at-rule it cannot recognise:&lt;br&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Warning:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Sub-optimal&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;approach&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Please&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;follow&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;previous&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;advice!&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;other&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;stuff&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"css.lint.unknownAtRules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ignore"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scss.lint.unknownAtRules"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ignore"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;But! &lt;strong&gt;What about typos?&lt;/strong&gt; We all make them, and I wouldn't trust myself writing things correctly any day :'D Better be more specific and let pass only the things we are aware of! &lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and inspiration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://byby.dev/at-rule-tailwind"&gt;How to fix the unknown at rule @tailwind warning&lt;/a&gt; by &lt;a href="https://byby.dev"&gt;byby.dev&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwindcss.com/docs/functions-and-directives"&gt;Tailwind's Functions &amp;amp; Directives documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cover: Tailwind logotype from &lt;a href="https://tailwindcss.com/brand"&gt;Tailwind Official Brand page&lt;/a&gt;, &lt;a href="https://www.freepik.com/free-vector/3d-abstract-background-with-paper-cut-flower-shape_18695224.htm"&gt; 3d abstract background with paper cut flower shape&lt;/a&gt; by &lt;a href="https://www.freepik.com/author/garrykillian"&gt;GarryKillian&lt;/a&gt; via &lt;a href="https://freepik.com"&gt;Freepik&lt;/a&gt;

Originally posted in &lt;a href="https://oh-no.ooo"&gt;oh-no.ooo&lt;/a&gt; (&lt;a href="https://www.oh-no.ooo/snippets/unknown-at-rule-apply-k-thx-bye"&gt;Unknown at rule @apply... k thx bye!&lt;/a&gt;), my personal website.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tailwindcss</category>
      <category>webdev</category>
      <category>vscode</category>
      <category>css</category>
    </item>
    <item>
      <title>Performance optimization with useMemo</title>
      <dc:creator>Lucy Love</dc:creator>
      <pubDate>Sun, 09 Jun 2024 17:08:15 +0000</pubDate>
      <link>https://forem.com/mahdava/performance-optimization-with-usememo-2nl4</link>
      <guid>https://forem.com/mahdava/performance-optimization-with-usememo-2nl4</guid>
      <description>&lt;p&gt;One of those things that you don't know enough, and then when you know somewhat you tend to use a bit too much is React beloved and behated &lt;a href="https://react.dev/reference/react/useMemo"&gt;useMemo hook&lt;/a&gt;. In my quest of trying to understand more the features of React that I use on a regular basis, I find myself in need to write more about this hook, clarifying what is it, when to use it and when not.&lt;/p&gt;

&lt;p&gt;So, let's get started and unravel this madness!&lt;/p&gt;

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

&lt;p&gt;Introduced in React 16.8, the useMemo hook is a built-in feature designed to memoize values and prevent unnecessary recalculations and re-renders, meaning that instead of calculating things on the fly, it will first check if that computation has already done and take the value already stored.&lt;/p&gt;

&lt;p&gt;... Wait wait wait! &lt;strong&gt;memoization what?!&lt;/strong&gt; What's that?!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.freecodecamp.org/news/author/gercocca/"&gt;Germán Cocca&lt;/a&gt; makes a great job at explaining this concept &lt;a href="https://www.freecodecamp.org/news/memoization-in-javascript-and-react/"&gt;in his article about Memoization in Javascript and React&lt;/a&gt;, and I will not try to rewrite it when he's already told it better than I ever can!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In programming, &lt;strong&gt;memoization is an optimization technique&lt;/strong&gt; that makes applications more efficient and hence faster. It does this by storing computation results in cache, and retrieving that same information from the cache the next time it's needed instead of computing it again.&lt;/p&gt;
&lt;br&gt;
&lt;p&gt;In simpler words, &lt;strong&gt;it consists of storing in cache the output of a function&lt;/strong&gt;, and making the function check if each required computation is in the cache before computing it.&lt;/p&gt;
&lt;br&gt;
  — &lt;a href="https://www.freecodecamp.org/news/author/gercocca/"&gt;Germán Cocca&lt;/a&gt; in &lt;a href="https://www.freecodecamp.org/news/memoization-in-javascript-and-react/"&gt;What is Memoization? How and When to Memoize in JavaScript and React&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;So far so good. Yes?! &lt;strong&gt;Nope&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I have heard that &lt;em&gt;useMemo should not always be used&lt;/em&gt; and this explanation makes me think instead that it always sounds like a good idea, so let's continue digging up a bit more more, but let's go the long route and let's see first how to implement it.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use useMemo
&lt;/h2&gt;

&lt;p&gt;The basic syntax for useMemo is&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;memoizedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="nf"&gt;computeExpensiveValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This line of code contains the function used to calculate the value and the dependency array. For example, consider a component that filters a list of items based on a search term:&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="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMemo&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;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;FilteredList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;searchTerm&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;filteredItems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&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;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;searchTerm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;searchTerm&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&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;filteredItems&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&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;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&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;In this example, we use useMemo to memoize the filtered list of items and avoid recalculating the filtered list every time the component renders. &lt;em&gt;Still sounds pretty good and still like I should actually be using it more than I actually do.&lt;/em&gt; 🤔&lt;/p&gt;

&lt;p&gt;Browsing various examples online, as you can see from the first snippet of code in this article, however, I find the emerging written pattern of using useMemo &lt;em&gt;only for expensive calculations&lt;/em&gt;, &lt;em&gt;computed expensive value&lt;/em&gt;, &lt;em&gt;expensive operations&lt;/em&gt;, and I finally start understanding that there is something particularly in mind for which useMemo is recommended.&lt;/p&gt;

&lt;p&gt;But what is an expensive calculation in JavaScript?&lt;/p&gt;

&lt;h2&gt;
  
  
  Expensive calculations
&lt;/h2&gt;

&lt;p&gt;Expensive calculations are &lt;strong&gt;tasks that require a significant amount of processing time and resources&lt;/strong&gt;: they might be time-consuming, memory-intensive, or computationally complex. What seems to fit in this category is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manipulating large strings&lt;/strong&gt;, such as parsing and transforming text&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transforming large datasets through iteration&lt;/strong&gt;, while performing multiple calculations on the data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sorting or filtering large arrays&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fetching data through APIs/databases&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Processing and manipulating big files&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rendering a top component&lt;/strong&gt; with a significant number of nested components and elements&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recursive algorithms&lt;/strong&gt;, advanced statistical calculations, matrices, weird formulas etc. etc. etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://react.dev/reference/react/useMemo"&gt;React useHook official documentation&lt;/a&gt; has a section &lt;a href="https://react.dev/reference/react/useMemo#how-to-tell-if-a-calculation-is-expensive"&gt;How to tell if a calculation is expensive?&lt;/a&gt; where it teaches us to use the console by adopting &lt;code&gt;console.time()&lt;/code&gt; and &lt;code&gt;console.timeEnd()&lt;/code&gt; to better determine the cost of our operations.&lt;/p&gt;

&lt;p&gt;Not all these operations are inherently worthy of useMemo though! There are at least a few things to consider.&lt;/p&gt;


&lt;h3&gt;
  
  
  1. How often is the operation performed?
&lt;/h3&gt;

&lt;p&gt;If the operation is performed frequently or triggered by state/props changes, and the result doesn't change as often, memoizing the result can prevent redundant recalculations, therefore improving overall performance.&lt;/p&gt;

&lt;p&gt;For example, if you have a big array of strings that needs to be formatted in a particular way, and you might want to list all of them in a nice HTML list, using useMemo might help avoiding slow renders in the UI.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  2. How reusable is the result of useMemo?
&lt;/h3&gt;

&lt;p&gt;The result is used within the component or passed down as props to child components; if the result is used multiple times, useMemo can indeed help avoid unnecessary recalculation.&lt;/p&gt;

&lt;p&gt;Think of a large file that you want to use in different sections of your app; it's definitely worth contemplating memoizing it.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Is it worth the memory consumption?
&lt;/h3&gt;

&lt;p&gt;As the memoized values are stored in memory until the component unmounts or the dependencies change, memoizing large datasets will definitely increase memory consumption; &lt;strong&gt;if the fetching from caching is faster than the recomputation of the calculations, perhaps useMemo might have a valid purpose&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you're fetching a big list and your interface freezes, perhaps yes, it's time to think about useMemo.&lt;/p&gt;



&lt;p&gt;In all of the above cases, and even more critical than for &lt;code&gt;useEffect&lt;/code&gt;, &lt;strong&gt;the dependencies of the memoized function need to be properly evaluated&lt;/strong&gt; to make sure that useMemo recalculates the memoized value only when necessary, as performance might otherwise ironically drop.&lt;/p&gt;

&lt;p&gt;In his article &lt;a href="https://maxrozen.com/understanding-when-use-usememo"&gt;Understand when to use useMemo&lt;/a&gt;, &lt;a href="https://twitter.com/RozenMD"&gt;Max Rozen&lt;/a&gt; puts it up in simple words:&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Don't use useMemo until you notice parts of your app are frustratingly slow. &lt;strong&gt;Premature optimisation is the root of all evil&lt;/strong&gt;, and throwing useMemo everywhere is premature optimisation.&lt;/p&gt;
— &lt;a href="https://twitter.com/RozenMD"&gt;Max Rozen&lt;/a&gt; in &lt;a href="https://maxrozen.com/understanding-when-use-usememo"&gt;Understand when to use useMemo&lt;/a&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  &lt;br&gt;"Premature optimization is the root of all evil"
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;This paragraph might be a tad too long and expanding on a topic that is not quite the purpose of this article; feel free to move to the next header if you already have a grasp about premature optimization.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Calling premature optimization &lt;em&gt;the root of all evil&lt;/em&gt; seems to be something rather common, and &lt;a href="https://effectiviology.com/itamar-shatz/"&gt;Dr. Itamar Shatz&lt;/a&gt; in his article about &lt;a href="https://effectiviology.com/premature-optimization/"&gt;Premature Optimization: Why It’s the “Root of All Evil” and How to Avoid It&lt;/a&gt; says that&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Premature optimization&lt;/strong&gt; involves trying to &lt;strong&gt;improve something&lt;/strong&gt; — especially with the goal of perfecting it — &lt;strong&gt;when it’s too early to do so&lt;/strong&gt;.&lt;/p&gt;

— &lt;a href="https://effectiviology.com/itamar-shatz/"&gt;Dr. Itamar Shatz&lt;/a&gt; in &lt;a href="https://effectiviology.com/premature-optimization/"&gt;Premature Optimization: Why It’s the “Root of All Evil” and How to Avoid It&lt;/a&gt;
&lt;/blockquote&gt;



&lt;p&gt;His article also shows that the famous &lt;em&gt;Premature optimization is the root of all evil&lt;/em&gt; sentence is a quote from the computer scientist &lt;a href="https://profiles.stanford.edu/donald-knuth"&gt;Donald Knuth&lt;/a&gt;, from his article &lt;a href="https://dl.acm.org/doi/10.1145/356635.356640"&gt;Structured Programming with go to Statements&lt;/a&gt;. The article is a reminder to developers not to spend too much time or resources optimizing parts of a program before they need to and especially before they have a working version.&lt;/p&gt;

&lt;p&gt;According to Donald Knuth, premature optimization leads to wasted effort, as you might end up optimizing parts of the code that don't have a significant impact on the overall performance, or even optimizing code that eventually gets removed or significantly changed.&lt;/p&gt;

&lt;p&gt;His recommendations are to &lt;strong&gt;first build a functional system&lt;/strong&gt;, &lt;strong&gt;then identify any performance issues&lt;/strong&gt;, and &lt;strong&gt;finally optimize critical parts that actually need optimization&lt;/strong&gt;, without forgetting that readability and maintainability are often more important than minor efficiency gains, especially in early development stages.&lt;/p&gt;

&lt;p&gt;Dr. Itamar Shatz lists out the &lt;a href="https://effectiviology.com/premature-optimization/#Dangers_of_premature_optimization"&gt;dangers of premature optimization&lt;/a&gt; in a few yet impactful points, which I recommend reading from his article.&lt;/p&gt;




&lt;p&gt;I have now some ideas on where useMemo could come at hand as well as potential dangers of premature optimization, but I still feel like the constraints for which it's recommended are still a bit unable to give a clear line. Perhaps it'd be beneficial to go the other route and analyze when &lt;em&gt;not&lt;/em&gt; to use useMemo.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  When not to use useMemo
&lt;/h2&gt;

&lt;p&gt;By what we've figured out before, if an operation is relatively simple, doesn't consume much processing time, and doesn't depend on frequently changing data, &lt;strong&gt;using useMemo will add unnecessary overhead without significant performance gains&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Therefore&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if a component &lt;strong&gt;doesn't have any expensive calculations&lt;/strong&gt; and &lt;strong&gt;doesn't render frequently&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;or the expensive operation is &lt;strong&gt;isolated to a specific part of the component that doesn't impact the overall rendering performance&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;or the expensive operation varies significantly between the instances where the component is used&lt;/li&gt;
&lt;li&gt;and we're trying to accommodate all sorts of devices that might not have a lot of memory available&lt;/li&gt;
&lt;li&gt;and &lt;strong&gt;the performance improvement is not noticeable by end-users&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;... &lt;strong&gt;we might find ourselves perhaps not in need of useMemo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We also need to consider that adding useMemo to memoize some calculations can make writing unit tests more complicated, and while it's not a reason to avoid useMemo, it's definitely worth to weigh the benefits of memoization also against the ease of testing and maintaining the code.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Example implementations
&lt;/h2&gt;

&lt;p&gt;From all this reading and writing, I can deduct that there are plausible usages where you expect to process a lot of data, that won't change as often, such as:&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;// Plausible usage of useMemo&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMemo&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;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BigProcessedList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="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;processedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&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;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Simulating an expensive computation&lt;/span&gt;
      &lt;span class="k"&gt;for &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;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;1&lt;/span&gt;&lt;span class="nx"&gt;e6&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return &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;ol&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;processedData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&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;index&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;item&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="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ol&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;Another plausible example would be:&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;// Plausible good use of useMemo&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMemo&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;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;EmployeeList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filter&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;filteredEmployees&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&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;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;emp&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;emp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;department&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;filter&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;employees&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;filter&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ul&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;filteredEmployees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;employee&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;li&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;employee&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/li&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ul&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;... And potentially, there could be so many bad/unrecommended implementations where there's no big computation needed and therefore useMemo is bringing no real benefit to the end user:&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;// Unoptimal use of useMemo&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMemo&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;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CombinedStringComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;propA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propB&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;combinedProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;propA&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;propB&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;propA&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;propB&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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;combinedProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&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;Ultimately, the trend with useMemo seems to be that as soon as people get to know more about it, they want to implement it, whereas &lt;strong&gt;it'd make more sense to leave it for only when the app clearly shows benefits from implementing it&lt;/strong&gt;. It sounds like a pretty good news to me as it means that most likely I don't have to change anything on my website as I don't seem to see anything particularly too slow... &lt;em&gt;yay!&lt;/em&gt; 😂&lt;/p&gt;

&lt;p&gt;I've truly enjoyed writing about this and I can't help but recommend strongly to read the sources/resources attached to the article; if you feel like I've miswritten something (which can very well be the cause as my best corrections often come days after I rewrote something), don't hesitate to mention that in the comments below!&lt;/p&gt;

&lt;p&gt;But before I leave...&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A brief note about useMemo vs. useCallback
&lt;/h2&gt;

&lt;p&gt;You'll also hear this one too! And while &lt;code&gt;useCallback&lt;/code&gt; is gonna be a topic for another day, let's just iron this one last thing out before we call it a day!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;useCallback&lt;/strong&gt; is similar to useMemo, but &lt;strong&gt;instead of memoizing the result of a function, it memoizes the actual function itself&lt;/strong&gt;, which is particularly useful when you have a component that receives a function as a prop and you want to prevent unnecessary re-rendering of child components that depend on that function. This means that if the dependencies of useCallback don't change, &lt;strong&gt;the same function instance is used, avoiding unnecessary re-renders of child components that depend on it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now out! Bye! :D&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and inspiration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://react.dev/reference/react/useMemo"&gt;Official React useHook documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://chat.openai.com/"&gt;ChatGPT&lt;/a&gt; prompt: &lt;code&gt;Can you help me write a good article on the What, Why and How of using useMemo hook?&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3schools.com/react/react_usememo.asp"&gt;W3School documentation on useMemo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.freecodecamp.org/news/memoization-in-javascript-and-react"&gt;What is Memoization? How and When to Memoize in JavaScript and React&lt;/a&gt; by &lt;a href="https://www.freecodecamp.org/news/author/gercocca/"&gt;Germán Cocca&lt;/a&gt; from &lt;a href="https://www.freecodecamp.org/"&gt;freeCodeCamp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://maxrozen.com/understanding-when-use-usememo"&gt;Understand when to use useMemo&lt;/a&gt; by &lt;a href="https://twitter.com/RozenMD"&gt;Max Rozen&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://effectiviology.com/premature-optimization/"&gt;Premature Optimization: Why It’s the “Root of All Evil” and How to Avoid It&lt;/a&gt; by &lt;a href="https://effectiviology.com/itamar-shatz/"&gt;Dr. Itamar Shatz&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cover: &lt;a href="https://www.freepik.com/free-vector/gradient-liquid-abstract-background_13346239.htm"&gt;Vector Liquid Background&lt;/a&gt; by &lt;a href="https://www.freepik.com/author/pikisuperstar"&gt;pikistar&lt;/a&gt; via &lt;a href="https://freepik.com"&gt;Freepik&lt;/a&gt;, &lt;a href="https://www.freepik.com/free-psd/3d-illustration-people-working-marketing_42937458.htm"&gt;People working marketing&lt;/a&gt; by &lt;a href="https://freepik.com"&gt;Freepik&lt;/a&gt;

Originally posted in &lt;a href="https://oh-no.ooo"&gt;oh-no.ooo&lt;/a&gt; (&lt;a href="https://www.oh-no.ooo/articles/performance-optimization-with-usememo"&gt;Performance optimization with useMemo&lt;/a&gt;), my personal website.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>performance</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Fixing Disqus 'Auto' theme switching when using Next.js + next-themes</title>
      <dc:creator>Lucy Love</dc:creator>
      <pubDate>Sat, 08 Jun 2024 09:19:07 +0000</pubDate>
      <link>https://forem.com/mahdava/fixing-disqus-auto-theme-switching-when-using-nextjs-next-themes-3l4k</link>
      <guid>https://forem.com/mahdava/fixing-disqus-auto-theme-switching-when-using-nextjs-next-themes-3l4k</guid>
      <description>&lt;p&gt;In &lt;a href="https://www.oh-no.ooo/articles/a-blasting-august-with-blaugust" rel="noopener noreferrer"&gt;my last year's post about the amazing Blaugust event&lt;/a&gt;, I've been mentioning my issue with setting up my &lt;a href="https://nextjs.org" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; site combined with &lt;a href="https://www.npmjs.com/package/next-themes" rel="noopener noreferrer"&gt;next-themes&lt;/a&gt; and &lt;a href="https://disqus.com/" rel="noopener noreferrer"&gt;Disqus&lt;/a&gt; commenting platform.&lt;/p&gt;

&lt;p&gt;This article is here to make sure I can share my solution, as for as simple it was it might help some people that stumble upon it. Let's start first with what issue I had, what I've done, so that we can walk together through the solution!&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What was the issue
&lt;/h2&gt;

&lt;p&gt;After following the &lt;a href="https://dev.to/luisca/step-by-step-guide-to-adding-dark-mode-and-multiple-themes-to-your-nextjs-app-15lh"&gt;Step-By-Step Guide to Adding Dark Mode and Multiple Themes to Your Next.js App&lt;/a&gt; written by &lt;a href="https://dev.to/luisca"&gt;Luis Cadillo&lt;/a&gt; (thank you pal!), I found myself with a neat Dark mode but my Disqus embed (installed through &lt;a href="https://www.npmjs.com/package/disqus-react" rel="noopener noreferrer"&gt;disqus-react npm package&lt;/a&gt;) would not update its theme properly, despite its theme settings being on &lt;code&gt;Auto&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F3UqieaGPLVgDYj3UwVSHnF%2F6a048c82fd500213b31979933da29d7a%2Fbuggy_disqus_theme.png%3Ffm%3Davif%26r%3D50" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F3UqieaGPLVgDYj3UwVSHnF%2F6a048c82fd500213b31979933da29d7a%2Fbuggy_disqus_theme.png%3Ffm%3Davif%26r%3D50" alt="Buggy Disqus theme change at the bottom of my articles"&gt;&lt;/a&gt;&lt;em&gt;Buggy Disqus theme change at the bottom of my articles&lt;/em&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;I checked that the settings in &lt;code&gt;&amp;lt;sitename&amp;gt;.disqus.com/admin/settings/general/&lt;/code&gt; were correct, but that didn't help.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F6UJHYV3ekkdBDgjEnGE9yP%2Ff02cdaa0483280661ac222555af511a1%2FScreenshot_2023-08-05_at_1.22.38.png%3Ffm%3Davif%26r%3D25%26w%3D600" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F6UJHYV3ekkdBDgjEnGE9yP%2Ff02cdaa0483280661ac222555af511a1%2FScreenshot_2023-08-05_at_1.22.38.png%3Ffm%3Davif%26r%3D25%26w%3D600" alt="Disqus settings for automatic detection of the color scheme"&gt;&lt;/a&gt;&lt;em&gt;Disqus settings for automatic detection of the color scheme.&lt;/em&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;My initial challenge was understanding how Disqus determined which theme to show in the page. Browsing the documentation I stumbled on a piece of useful information:&lt;/p&gt;

&lt;blockquote&gt;
&lt;span&gt;Light vs. dark color scheme&lt;/span&gt;&lt;br&gt;
A light or dark color scheme is automatically selected based on your site's stylesheets.
&lt;br&gt;
&lt;br&gt;
&lt;span&gt;How is the color scheme determined?&lt;/span&gt;&lt;br&gt;
&lt;ul&gt;
  &lt;li&gt;The light scheme is loaded when &lt;strong&gt;the text color Disqus inherits from your site has &amp;gt;= 50% gray contrast&lt;/strong&gt;: between color: #000000; and color: #787878;&lt;/li&gt;

  &lt;li&gt;The dark scheme is loaded in all other instances.&lt;/li&gt;
&lt;/ul&gt;
— &lt;a href="https://help.disqus.com/en/articles/1717201-disqus-appearance-customizations" rel="noopener noreferrer"&gt;Disqus Appearance Customization&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
This allowed me to understand how the color scheme in Disqus was determined, but not yet why my changes wouldn't work. White text on a white background isn't quite the 'Auto' mode I was hoping for!&lt;/p&gt;

&lt;p&gt;Searching for some help in &lt;a href="https://stackoverflow.com/" rel="noopener noreferrer"&gt;StackOverflow&lt;/a&gt;, I found my very same problem but no answer to it: &lt;a href="https://stackoverflow.com/questions/75921829/disqus-theme-not-matching-background-when-changing-blog-theme-from-dark-to-light" rel="noopener noreferrer"&gt;Disqus theme not matching background when changing blog theme from dark to light&lt;/a&gt;. Despite not finding a solution, I found some comfort in seeing that other peeps had my same problem and that it wasn't just me being... well... dumb xD&lt;/p&gt;

&lt;p&gt;A little bit more digging and googling around brought me to another StackOverflow post, &lt;a href="https://stackoverflow.com/questions/75787047/disqus-comments-dark-mode-renders-with-white-background?rq=2" rel="noopener noreferrer"&gt;Disqus comments Dark mode renders with white background&lt;/a&gt; where &lt;a href="https://stackoverflow.com/users/10312920/ken-mueller" rel="noopener noreferrer"&gt;Ken Mueller&lt;/a&gt; mentions to "Remove the &amp;lt;meta name="color-scheme" content="dark" /&amp;gt; from your document.".&lt;/p&gt;

&lt;p&gt;Now, I didn't have such a thing in my Next.js ecosystem, but I noticed that next-themes applied a &lt;code&gt;style="color-scheme: dark;"&lt;/code&gt; to my main HTML tag.&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;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"dark"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"color-scheme: dark;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F7gl5NhSwwFZc4LgivqyAsN%2F7a8d2bb8d723d383321339d100e41862%2FScreenshot_2023-08-05_at_12.43.25.png%3Ffm%3Davif%26r%3D25%26w%3D600" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F7gl5NhSwwFZc4LgivqyAsN%2F7a8d2bb8d723d383321339d100e41862%2FScreenshot_2023-08-05_at_12.43.25.png%3Ffm%3Davif%26r%3D25%26w%3D600" alt="My Chrome inspector showing that the HTML tag in my website had this extra style="&gt;&lt;/a&gt;&lt;em&gt;My Chrome inspector showing that the HTML tag in my website had this extra &lt;code&gt;style="color-scheme: dark;"&lt;/code&gt; property.&lt;/em&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Since messing around with the inspector costs nothing, I've simply tried to remove the content of &lt;code&gt;style&lt;/code&gt; and don't you know... it worked!&lt;/p&gt;

&lt;p&gt;Checking &lt;a href="https://www.npmjs.com/package/next-themes" rel="noopener noreferrer"&gt;next-themes documentation&lt;/a&gt;, reading the codebase and bashing my head a little, I seem to understand that this HTML style change comes from the &lt;code&gt;enableColorScheme&lt;/code&gt; setting of next-themes, which by default is set as &lt;code&gt;true&lt;/code&gt;, but for my case would need to be set &lt;code&gt;false&lt;/code&gt;.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MyApp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pageProps&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;AppProps&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="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ThemeProvider&lt;/span&gt; 
        &lt;span class="nx"&gt;attribute&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;class&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
        &lt;span class="nx"&gt;enableColorScheme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;}&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="nx"&gt;Provider&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;}&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="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;pageProps&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Provider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/ThemeProvider&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&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;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;MyApp&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Wohoo! Works like a charm!&lt;/p&gt;

&lt;p&gt;But no, wait!&lt;/p&gt;

&lt;p&gt;Now if I am in an article page and I want to switch the theme there, my &lt;code&gt;&amp;lt;DiscussionEmbed&amp;gt;&lt;/code&gt; component from  &lt;a href="https://www.npmjs.com/package/disqus-react" rel="noopener noreferrer"&gt;disqus-react&lt;/a&gt; won't update automatically! So what do we do now?&lt;/p&gt;

&lt;p&gt;I happen to have this component wrapped in a container for easier setup on my page, and I know that React would re-render a component should its key change... so 1 + 1 I had my 2:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DisqusComments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;DisqusCommentsProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 
  &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Import the name of the theme with useTheme() hook&lt;/span&gt;
  &lt;span class="c1"&gt;// from next-themes&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;theme&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useTheme&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;disqusConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="c1"&gt;// Use it as a key={theme} for the DiscussionEmbed component&lt;/span&gt;
  &lt;span class="c1"&gt;// so that it will re-render should the theme change&lt;/span&gt;
  &lt;span class="k"&gt;return &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;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-14&lt;/span&gt;&lt;span class="dl"&gt;"&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="nx"&gt;DiscussionEmbed&lt;/span&gt; 
        &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
        &lt;span class="nx"&gt;shortname&lt;/span&gt;&lt;span class="o"&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;oh-no&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
        &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;disqusConfig&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
       &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&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;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;DisqusComments&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;p&gt;Basically, I'll use the name of the theme to determine whether the Disqus component should re-render, and should someone change the theme in an article page, &lt;strong&gt;the Disqus comment section will reload with the correct theme&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;At last, all I wanted!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F37HN4qOVbiyzNuHZEKBPaa%2F490dbc65f7935bb6555b17fe6a4bcabd%2FDisqus_comment_section_light_dark_theme.png%3Ffm%3Davif%26r%3D25" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F37HN4qOVbiyzNuHZEKBPaa%2F490dbc65f7935bb6555b17fe6a4bcabd%2FDisqus_comment_section_light_dark_theme.png%3Ffm%3Davif%26r%3D25" alt="My website Disqus section adapting to both dark and light color schemes. Yay!"&gt;&lt;/a&gt;&lt;em&gt;My website Disqus section adapting to both dark and light color schemes. Yay!&lt;/em&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Let me know if this helped you somehow, if you had the same issue or if somehow it brought you some help understanding a bit more about the problem for your own specific case!&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and inspiration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/luisca/step-by-step-guide-to-adding-dark-mode-and-multiple-themes-to-your-nextjs-app-15lh" rel="noreferrer noopener"&gt;Step-By-Step Guide to Adding Dark Mode and Multiple Themes to Your Next.js App&lt;/a&gt; by &lt;a href="https://dev.to/luisca" rel="noreferrer noopener"&gt;Luis Cadillo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/next-themes" rel="noreferrer noopener"&gt;next-themes npm package&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/disqus-react" rel="noreferrer noopener"&gt;disqus-react npm package&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stackoverflow.com/questions/75921829/disqus-theme-not-matching-background-when-changing-blog-theme-from-dark-to-light" rel="noreferrer noopener"&gt;Disqus theme not matching background when changing blog theme from dark to light&lt;/a&gt; from &lt;a href="https://stackoverflow.com/" rel="noreferrer noopener"&gt;StackOverflow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stackoverflow.com/questions/75787047/disqus-comments-dark-mode-renders-with-white-background?rq=2" rel="noreferrer noopener"&gt;Disqus comments Dark mode renders with white background&lt;/a&gt; from &lt;a href="https://stackoverflow.com/" rel="noreferrer noopener"&gt;StackOverflow&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cover: &lt;a href="https://www.freepik.com/free-psd/3d-rendering-graphic-design_31283887.htm" rel="noreferrer noopener"&gt;3D rendering of graphic design&lt;/a&gt; by &lt;a href="https://www.freepik.com/author/freepik" rel="noreferrer noopener"&gt;Freepik&lt;/a&gt;, &lt;a href="https://www.freepik.com/free-vector/geometric-circle-background-desktop-wallpaper-with-multicolors-vector_18220903.htm" rel="noreferrer noopener"&gt;Vector geometric background&lt;/a&gt; by &lt;a href="https://www.freepik.com/author/rawpixel-com" rel="noreferrer noopener"&gt;rawpixel.com&lt;/a&gt; via &lt;a href="https://freepik.com" rel="noreferrer noopener"&gt;Freepik&lt;/a&gt;, blurred code image created with &lt;a href="https://carbon.now.sh" rel="noreferrer noopener"&gt;Carbon&lt;/a&gt;, Next.js logo from &lt;a href="https://nextjs.org" rel="noreferrer noopener"&gt;Next.js official website&lt;/a&gt;, Disqus logo from &lt;a href="https://disqus.com/brand/" rel="noreferrer noopener"&gt;Disqus Brand and Logos official material&lt;/a&gt;

Originally posted in &lt;a href="https://www.oh-no.ooo/" rel="noopener noreferrer"&gt;oh-no.ooo&lt;/a&gt; (&lt;a href="https://www.oh-no.ooo/articles/fixing-disqus-auto-theme-switching-when-using-next-js-next-themes" rel="noopener noreferrer"&gt;Fixing Disqus 'Auto' theme switching when using Next.js + next-themes&lt;/a&gt;), my personal website.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>disqus</category>
      <category>nextjs</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Level up your Tailwind game</title>
      <dc:creator>Lucy Love</dc:creator>
      <pubDate>Fri, 07 Jun 2024 20:28:07 +0000</pubDate>
      <link>https://forem.com/mahdava/level-up-your-tailwind-game-3275</link>
      <guid>https://forem.com/mahdava/level-up-your-tailwind-game-3275</guid>
      <description>&lt;p&gt;This is my first article in Dev.to, please be patient with the poor markdown-ing!&lt;/p&gt;




&lt;p&gt;Alright, this article might or might not be for you.&lt;/p&gt;

&lt;p&gt;If you're the type of person that finds some Tailwind UI components and copies all the classes without any second thought, this might be for you.&lt;/p&gt;

&lt;p&gt;If you're passionate about Tailwind and you appreciate getting creative with its utilitarian classes, this might be for you.&lt;/p&gt;

&lt;p&gt;If you struggle with Tailwind and wonder &lt;em&gt;why can't we just stick to plain old CSS&lt;/em&gt;, this might be for you.&lt;/p&gt;

&lt;p&gt;If you don't like repetition and suspect that (besides wasting your time with the previous statements) some of the things that I'll show here are something you're already aware of, this might still be for you — repetition can't be that bad and I really tried to bring in something for everybody!&lt;/p&gt;

&lt;p&gt;The idea here is to &lt;strong&gt;go through a Tailwind speed-run and find things that could help you use it more efficiently&lt;/strong&gt;. And if nothing resonates with you, share with me in the comment section what did I miss :D&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(And yes, the assumption is that you use VSCode, and occasionally Next.js for a thing or two, although a lot of these topics remain valid also with other frameworks.)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's get started then, shall we?&lt;/p&gt;

&lt;p&gt;Before you proceed reading, let's make sure you are already using &lt;a href="https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss" rel="noopener noreferrer"&gt;Tailwind CSS Intellisense&lt;/a&gt;, because if you're not, you definitely should. It's impossible to remember all the classes that Tailwind offers, and a little while we type them out is really appreciated!&lt;/p&gt;

&lt;p&gt;Speaking of classes...&lt;/p&gt;


&lt;h2&gt;
  
  
  Classes, classes everywhere!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F6cofV2U5rxDoRXjqVmbyFy%2F4c80c2a0de01e3282adb73cdaf04496e%2Fclasses_classes_everywhere.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F6cofV2U5rxDoRXjqVmbyFy%2F4c80c2a0de01e3282adb73cdaf04496e%2Fclasses_classes_everywhere.jpeg" alt="The typical ToyStory meme with Buzz and Woody looking up. The top text says 'classes' and the bottom text says 'classes everywhere' to emphasise on the amount of CSS classes people have to deal with usually when they start with Tailwind. Image made at imgflip.com"&gt;&lt;/a&gt;Meme generated with &lt;a href="https://imgflip.com/memegenerator" rel="noopener noreferrer"&gt;Imgflip Meme Generator&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Yes, let's make sure we start with the easy-peasy. Lots of people complain that Tailwind &lt;em&gt;litters&lt;/em&gt; the project components with hecklots of classes, making it difficult to read through the component. To them I tell... have you heard of &lt;a href="https://marketplace.visualstudio.com/items?itemName=stivo.tailwind-fold" rel="noopener noreferrer"&gt;Tailwind Fold&lt;/a&gt; by &lt;a href="https://marketplace.visualstudio.com/publishers/stivo" rel="noopener noreferrer"&gt;Stivo&lt;/a&gt;? No? Now you have.&lt;/p&gt;

&lt;p&gt;In his &lt;a href="https://flaviocopes.com/hiding-classes-in-vs-code/" rel="noopener noreferrer"&gt;article about Hiding classes in VSCode&lt;/a&gt;, our friend and constant source of inspiration &lt;a href="https://flaviocopes.com/" rel="noopener noreferrer"&gt;Flavio Copes&lt;/a&gt; goes through a quick look at how this VSCode extension simply shows and hides the classes through a simple click.&lt;/p&gt;

&lt;p&gt;While this is a worthy approach, you might not want to click to toggle classes visibility (I know I don't), and therefore the next suggestion would be...&lt;/p&gt;


&lt;h2&gt;
  
  
  Tailwind + Sass (and a sprinkle of &lt;code&gt;@mixin&lt;/code&gt; if you will)
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(We'll assume you're using Next.js, because, let's be honest, what else would you want to use if you had a choice?! I'm kidding, kinda :D)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We all love (I hope, otherwise why are you here?!) the power of Tailwind, but separating the functional part of a component from its styling is still a dream for many. The good news? You can achieve this by combining Tailwind with Sass! You just need to install Sass and everything will start working right off the bat!&lt;/p&gt;

&lt;p&gt;Joaquin Collado, through &lt;a href="https://www.rootstrap.com/" rel="noopener noreferrer"&gt;Rootstrap&lt;/a&gt;, has &lt;a href="https://www.rootstrap.com/blog/how-to-use-module-scss-with-tailwind-in-next-js" rel="noopener noreferrer"&gt;an easy guide on how to Use Module SCSS with Tailwind in Next.js&lt;/a&gt;. Let's follow along!&lt;/p&gt;

&lt;p&gt;First, install Sass&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; sass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, create the &lt;code&gt;.module.scss&lt;/code&gt; for your components, e.g. &lt;code&gt;Button.module.scss&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;@apply&lt;/span&gt; &lt;span class="nt"&gt;p-4&lt;/span&gt; &lt;span class="nt"&gt;rounded&lt;/span&gt; &lt;span class="nt"&gt;bg-blue-500&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;Import the styles in the component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;styles&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;./Button.module.scss&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;And finally use them in your React component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Click Me&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ta-da! 🎉 You will now be able, for most things, to separate the Tailwind classes from your component.&lt;/p&gt;

&lt;p&gt;And you know what?! This approach allows you to use also the &lt;code&gt;@mixin&lt;/code&gt; properties if you're used to them!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mixins allow you to define styles that can be re-used throughout your stylesheet. They make it easy to avoid using non-semantic classes like &lt;code&gt;.float-left&lt;/code&gt;, and to distribute collections of styles in libraries.&lt;/p&gt;
— &lt;a href="https://sass-lang.com/documentation/at-rules/mixin/" rel="noopener noreferrer"&gt;@mixin and @include&lt;/a&gt; explanation from the &lt;a href="https://sass-lang.com/" rel="noopener noreferrer"&gt;official Sass documentation&lt;/a&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a title="CodeSandbox Tailwind + Sass + @mixin demo repository" href="https://codesandbox.io/p/github/mahdava/quirky-kiwi/main?amp%3Bembed=1&amp;amp;file=%2Fcomponents%2FsassButton%2FsassButton.tsx&amp;amp;embed=1" rel="noopener noreferrer"&gt;Have a look at this demo repository in CodeSandbox where you can see Tailwind + Sass + a simple implementation of &lt;code&gt;@mixin&lt;/code&gt; in action&lt;/a&gt;, or — if you prefer — &lt;a href="https://github.com/mahdava/quirky-kiwi" rel="noopener noreferrer"&gt;test this implementation of Tailwind + Sass + &lt;code&gt;@mixin&lt;/code&gt; locally by cloning it from GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So, let's take it slow and check... what do we have over there?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// page.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;SassButton&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/components/sassButton/sassButton&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SassButton&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello, I am a simple button&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;SassButton&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SassButton&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"block mt-4"&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"cancel"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    Me too!
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;SassButton&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SassButton&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"w-full m-2"&lt;/span&gt; &lt;span class="na"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    I am a variant that takes in
    both color and optional text color
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;SassButton&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have a poorly-named &lt;code&gt;SassButton&lt;/code&gt; component that can accept two props (ignoring the children, in our case the text we want our button to have), &lt;code&gt;className&lt;/code&gt; and &lt;code&gt;variant&lt;/code&gt;. Both props are optional, and while we get later to &lt;code&gt;className&lt;/code&gt; and best practices on how to use that, let's focus on the &lt;code&gt;variant&lt;/code&gt; part.&lt;/p&gt;

&lt;p&gt;Now, moving to the button component&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// SassButton.tsx&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;cx&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;classnames&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;FC&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&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="nx"&gt;styles&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./sassButton.module.scss&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SassButtonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&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="s2"&gt;cancel&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="s2"&gt;alert&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ReactElement&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;SassButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SassButtonProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;variant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;default&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;children&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;cx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button-&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;variant&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; 
    &lt;span class="nx"&gt;className&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;SassButton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we use the &lt;code&gt;variant&lt;/code&gt; prop to determine what style the button will inherit from our &lt;code&gt;sassButton.module.scss&lt;/code&gt; (which will be &lt;code&gt;button-&amp;lt;variant_name&amp;gt;&lt;/code&gt;), and when no variant is set we just set its value to &lt;code&gt;default&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's finally have a look at the Sass module.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;button-styles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="nv"&gt;$button-bg-color&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
&lt;span class="nv"&gt;$button-text-color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"white"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$button-bg-color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$button-text-color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;@apply&lt;/span&gt; &lt;span class="nt"&gt;p-4&lt;/span&gt; &lt;span class="nt"&gt;rounded&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.button-default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// here you can pass the background color&lt;/span&gt;
  &lt;span class="c1"&gt;// text color will use the default from the @mixin&lt;/span&gt;
  &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;button-styles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.button-alert&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// here you can pass both background color and text color&lt;/span&gt;
  &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;button-styles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;orange&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.button-cancel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;button-styles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;#ff0000&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;Our sass module starts with the overall shape and appearance of our button through the &lt;code&gt;@mixin&lt;/code&gt; directive called &lt;code&gt;button-styles&lt;/code&gt;, and it uses &lt;code&gt;$button-bg-color&lt;/code&gt; and &lt;code&gt;$button-text-color&lt;/code&gt; as variables to customize the color of the background and the text of the button.&lt;/p&gt;

&lt;p&gt;Subsequently, we reuse the same setup by providing the variants &lt;em&gt;default&lt;/em&gt; &lt;em&gt;alert&lt;/em&gt; and &lt;em&gt;cancel&lt;/em&gt; with the desired background and text color (the latter being optional and defaulting to &lt;em&gt;white&lt;/em&gt; if nothing else is specified) by calling on &lt;code&gt;button-style&lt;/code&gt; through the &lt;code&gt;@include&lt;/code&gt; directive.&lt;/p&gt;

&lt;p&gt;(Congratulations, you just had an absolute speed-run on how to use &lt;code&gt;@mixin&lt;/code&gt; if this is your first time!)&lt;/p&gt;

&lt;p&gt;Notice that with this approach nothing forbids us to use Tailwind classes at any point; we are already using simultaneously traditional CSS properties combined with Tailwind classes. Allegedly, no one could stop us from doing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.button-cancel&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;@include&lt;/span&gt; &lt;span class="nd"&gt;button-styles&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mh"&gt;#ff0000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;@apply&lt;/span&gt; &lt;span class="nt"&gt;text-xs&lt;/span&gt; &lt;span class="nt"&gt;underline&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;and it would be up to us to choose how to organise and create all the variants.&lt;/p&gt;

&lt;p&gt;Heck, you might and think "why bringing &lt;code&gt;@mixin&lt;/code&gt; up at all?" and in general I would say that Tailwind on its own is more than enough, but in a system that needs to contemplate multiple variants of the same component, &lt;code&gt;@mixin&lt;/code&gt; could be the solution you were looking for — also, my objective with this article is to showcase more possibilities on how to work with Tailwind!&lt;/p&gt;

&lt;p&gt;(Also... for some reason, I am not successful setting up a default value for &lt;code&gt;$button-bg-color&lt;/code&gt;, if you know why let me know in the comments how to set all the parameters optional!)&lt;/p&gt;




&lt;p&gt;So do you remember that &lt;code&gt;className&lt;/code&gt; I said I was gonna mention again later? Now it's the time, for we are going to talk about...&lt;/p&gt;


&lt;h2&gt;
  
  
  The misunderstood art of managing space between elements and sections
&lt;/h2&gt;

&lt;p&gt;If you're working with a good design system, I'd expect everything to be well-divided in &lt;strong&gt;sections&lt;/strong&gt; and you being blessed with the consistency of everything spaced &lt;em&gt;consistently&lt;/em&gt; throughout the project.&lt;/p&gt;

&lt;p&gt;A good design system would have an atomic structure, where each smallest &lt;strong&gt;atom&lt;/strong&gt; is a discernible component that may coincide to one or a few more HTML elements in the page that provide some value. Using these atoms/components together would form &lt;strong&gt;molecules&lt;/strong&gt;, which would be the equivalent of a header, footer, sidebar — which all are &lt;strong&gt;sections&lt;/strong&gt; of a website page — and a full page could be then considered an &lt;strong&gt;organism&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The reality is that most times, &lt;strong&gt;designers work in components and not in sections&lt;/strong&gt;, meaning that there's no real concept of molecules, just atoms and straight into organisms. This implies that there is easily a lot of discrepancy on how much space there can be above an heading or below a section based on the rest of the content of the page if there is no clear demarcation of the end of a section and the beginning of another.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F4JIxIJWuwdWQLMEoJdgF30%2Fc2bb17815dd812a8f65ed28532562760%2Fbad_spacing_in_design.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F4JIxIJWuwdWQLMEoJdgF30%2Fc2bb17815dd812a8f65ed28532562760%2Fbad_spacing_in_design.png" alt="Example of bad spacing in a design system and/or its implementation"&gt;&lt;/a&gt;In the above image (titled &lt;em&gt;Bad spacing&lt;/em&gt;), the elements have an &lt;strong&gt;add a margin down approach&lt;/strong&gt; to space components between each other. While this might still result in the desired appearance for some pages, reusing the same components in new pages will cause issues as the margins might differ. There is no clarity on how much space the navigation or the article header should have, nor how much their components should have space around them.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F2GnHsEx4Y2uK59iRuumJ4R%2Fe99c6c93d925b5759a2e51c17ecce6d5%2Fbetter_spacing_in_design.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F2GnHsEx4Y2uK59iRuumJ4R%2Fe99c6c93d925b5759a2e51c17ecce6d5%2Fbetter_spacing_in_design.png" alt="Example of a better spacing handling in a design system and/or its implementation"&gt;&lt;/a&gt;In this other image (titled "Better spacing") we can see an improved understanding of spacing between elements and a clearer use of sections. We are able to deduct how much space there should be around each component, not only under, and which part of the overall space doesn't really belong to any component.&lt;/p&gt;

&lt;p&gt;(Yes, I know, some components such as "Tags" should also be able to see the settings of each single "Tag" and in my picture they are all compact together, but I just wanted to get the spacing point across... :D)&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;While we are not here to discuss about design systems (although I would anytime), I want you to acknowledge that &lt;strong&gt;components shouldn't directly take care of accommodating spacing based to their position in a page&lt;/strong&gt;, but rather, they should be able to &lt;strong&gt;circumstantially receive and accommodate their spacing directives&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;What do I mean by circumstantially? Nothing more than accepting classes related to the spacing that is needed for the page where the component will show up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codesandbox.io/p/github/mahdava/snappy-melon/main?file=%2Fapp%2Farticles%2Fpage.tsx&amp;amp;workspaceId=ffe5e611-b2f7-47e3-8cb3-c95e41c7d6b5" rel="noopener noreferrer"&gt;You can check this CodeSandbox to test how to give arbitrary spacing classes to a component&lt;/a&gt; or, like before, &lt;a href="https://github.com/mahdava/snappy-melon/blob/main/app/page.tsx" rel="noopener noreferrer"&gt;you can check how to give arbitrary spacing classes from this GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's dig into the code.&lt;/p&gt;

&lt;p&gt;We have three different pages, &lt;code&gt;app/pages.tsx&lt;/code&gt;, &lt;code&gt;app/articles/page.tsx&lt;/code&gt; and &lt;code&gt;app/about/page.tsx&lt;/code&gt; that make use of the same &lt;code&gt;&amp;lt;HeaderTitle&amp;gt;&lt;/code&gt; component. The homepage uses the component without worrying much about its spacing in the page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/page.tsx&lt;/span&gt;

&lt;span class="cm"&gt;/* ... */&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HeaderTitle&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Lorem ipsum"&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;This&lt;/span&gt; &lt;span class="na"&gt;HeaderTitle&lt;/span&gt; &lt;span class="na"&gt;component&lt;/span&gt; 
&lt;span class="na"&gt;doesn&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="na"&gt;t&lt;/span&gt; &lt;span class="na"&gt;have&lt;/span&gt; &lt;span class="na"&gt;any&lt;/span&gt; &lt;span class="na"&gt;extra&lt;/span&gt; &lt;span class="na"&gt;spacing&lt;/span&gt; &lt;span class="na"&gt;setting&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meanwhile, both &lt;code&gt;app/articles/page.tsx&lt;/code&gt; and &lt;code&gt;app/about/page.tsx&lt;/code&gt; infer an extra &lt;code&gt;className&lt;/code&gt; property that allows the &lt;code&gt;&amp;lt;HeaderTitle&amp;gt;&lt;/code&gt; component to take up different space in the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app/articles/page.tsx&lt;/span&gt;

&lt;span class="cm"&gt;/* ... */&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HeaderTitle&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Lorem ipsum"&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;&lt;span class="na"&gt;This&lt;/span&gt; &lt;span class="na"&gt;HeaderTitle&lt;/span&gt; &lt;span class="na"&gt;has&lt;/span&gt; &lt;span class="na"&gt;some&lt;/span&gt; &lt;span class="na"&gt;extra&lt;/span&gt; &lt;span class="na"&gt;margin&lt;/span&gt; 
&lt;span class="na"&gt;around&lt;/span&gt; &lt;span class="na"&gt;it&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt; &lt;span class="na"&gt;fit&lt;/span&gt; &lt;span class="na"&gt;better&lt;/span&gt; &lt;span class="na"&gt;something&lt;/span&gt; &lt;span class="na"&gt;like&lt;/span&gt; &lt;span class="na"&gt;an&lt;/span&gt; &lt;span class="na"&gt;article&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="err"&gt;"&lt;/span&gt;
  &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"my-24 mx-12"&lt;/span&gt; &lt;span class="c1"&gt;// we added margins for this page&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="cm"&gt;/* ... */&lt;/span&gt;

&lt;span class="c1"&gt;// app/about/page.tsx&lt;/span&gt;

&lt;span class="cm"&gt;/* ... */&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HeaderTitle&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Lorem ipsum"&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          This HeaderTitle shows how much 
          flexibility you can have
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          while the component itself doesn&lt;span class="ni"&gt;&amp;amp;apos;&lt;/span&gt;t have 
          to include natively any &lt;span class="ni"&gt;&amp;amp;apos;&lt;/span&gt;fixed&lt;span class="ni"&gt;&amp;amp;apos;&lt;/span&gt; 
          position
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="si"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// with this approach, we can also infer&lt;/span&gt;
  &lt;span class="c1"&gt;// other styles related to the position of the element&lt;/span&gt;
  &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"fixed right-0 top-24"&lt;/span&gt;

&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="cm"&gt;/* ... */&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point here is that &lt;strong&gt;the code of the &lt;code&gt;&amp;lt;HeaderTitle&amp;gt;&lt;/code&gt; component itself remains untouched and un-duplicated, while its spacing properties are relative to the contexts it gets used on, allowing for flexibility of usage across different pages and different needs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You might want to argue now "couldn't we just wrap the component into another div whenever we need more space around it?", and while that is possible, it also creates extra elements that might create challenges while delivering semantic HTML. Also, it really helps us categorizing which classes we need for its spacing and positioning, and which ones are for the component itself.&lt;/p&gt;

&lt;p&gt;Which, guess what, leads us straight into the next topic!&lt;/p&gt;



&lt;h2&gt;
  
  
  Grouping by purpose for the sake of readability
&lt;/h2&gt;

&lt;p&gt;It takes absolutely nothing to make Tailwind classes difficult to digest; you check one component's styling and all you see is a long list of classes and no quick glance will prevent you from mistakenly apply a second &lt;code&gt;mx-&lt;/code&gt; class or so. &lt;/p&gt;

&lt;p&gt;So, next in my personal recommended Tailwind best-practices, is to think about what each class is doing — layout, spacing, typography, colors, etc. — and group by that!&lt;/p&gt;

&lt;p&gt;For example, instead of writing&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mt-4 bg-blue-500 text-white p-6 rounded-lg shadow-lg hover:bg-blue-700"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- content --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could organize them like 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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-6 mt-4 rounded-lg shadow-lg bg-blue-500 text-white hover:bg-blue-700"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- content --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Grouping similar classes together makes it easier to read and understand what stylings are being applied to the element. &lt;/p&gt;

&lt;p&gt;If it sounds daunting as a task, worry not! Someone has already thought of a VSCode extension, &lt;a href="https://marketplace.visualstudio.com/items?itemName=Trapfether.tailwind-raw-reorder" rel="noopener noreferrer"&gt;Tailwind Raw Reorder&lt;/a&gt;, that will take care of the sorting for you! (And apparently, it also works in &lt;code&gt;module.scss&lt;/code&gt; files without any extra configuration!)&lt;/p&gt;

&lt;p&gt;The order that the extension proposes is as follows (or at least ChatGPT think it is — at least I couldn't find this from anywhere else):&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
&lt;strong&gt;Layout:&lt;/strong&gt; container, box-border, box-content, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Positioning:&lt;/strong&gt; static, fixed, absolute, relative, sticky, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flex and Grid:&lt;/strong&gt; flex, inline-flex, grid, inline-grid, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spacing:&lt;/strong&gt; m-0, p-0, space-x-0, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sizing:&lt;/strong&gt; w-full, h-full, max-w-full, min-h-full, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Typography:&lt;/strong&gt; font-sans, text-sm, font-bold, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Background:&lt;/strong&gt; bg-white, bg-opacity-50, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Border:&lt;/strong&gt; border, border-0, rounded, ring, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Effects:&lt;/strong&gt; shadow, opacity-0, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transitions and Transforms:&lt;/strong&gt; transition, duration-300, ease-in, scale-100, etc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Miscellaneous:&lt;/strong&gt; cursor-pointer, select-none, etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://www.reddit.com/r/tailwindcss/comments/1720acu/vscode_tailwind_class_reorder_extension/" rel="noopener noreferrer"&gt;You can read more about the development journey of Tailwind Raw Reorder on Reddit&lt;/a&gt;, where people talk also about the &lt;a href="https://tailwindcss.com/blog/automatic-class-sorting-with-prettier" rel="noopener noreferrer"&gt;official recommendation for Automatic class sorting with Tailwind&lt;/a&gt; (which I don't recommend anymore because it only sorts classes alphabetically, although I wouldn't necessarily diss, as &lt;a href="https://www.oh-no.ooo/snippets/tailwind-automatic-class-sorting-with-prettier" rel="noopener noreferrer"&gt;I did like the combo of Tailwind + Prettier it when I discovered its existence&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;It is fair to note that &lt;a href="https://marketplace.visualstudio.com/items?itemName=Trapfether.tailwind-raw-reorder" rel="noopener noreferrer"&gt;Tailwind Raw Reorder&lt;/a&gt; by &lt;a href="https://marketplace.visualstudio.com/publishers/Trapfether" rel="noopener noreferrer"&gt;Andrew Trefethen&lt;/a&gt; is a fork of &lt;a href="https://marketplace.visualstudio.com/items?itemName=heybourn.headwind" rel="noopener noreferrer"&gt;the now dated Headwind VSCode extension&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Well damn, if this isn't all that you need to make the most out of Tailwind in a smart way!&lt;/p&gt;

&lt;p&gt;But wait! There's more!&lt;/p&gt;



&lt;h2&gt;
  
  
  Tailwind Merge to the rescue
&lt;/h2&gt;

&lt;p&gt;While I've already written &lt;a href="https://www.oh-no.ooo/snippets/tailwind-merge-clean-your-code-by-removing-conflicting-styling" rel="noopener noreferrer"&gt;a small snippet about Tailwind Merge&lt;/a&gt;, let me reiterate here what's for.&lt;/p&gt;

&lt;p&gt;Like the name suggests, &lt;a href="https://www.npmjs.com/package/tailwind-merge" rel="noopener noreferrer"&gt;&lt;code&gt;tailwind-merge&lt;/code&gt; npm package&lt;/a&gt; by &lt;a href="https://github.com/dcastil" rel="noopener noreferrer"&gt;Dany Castillo&lt;/a&gt; offers a solution that combines and reuses Tailwind utility classes.&lt;/p&gt;

&lt;p&gt;Suppose you have a button component that can be either primary or secondary, with different styles for each state, some styles taken from a &lt;code&gt;button.module.scss&lt;/code&gt; and perhaps with something else inherited by &lt;code&gt;className&lt;/code&gt; as we have seen is possible from above (oh god, what a mess — I am legally obligated to mention the classic &lt;em&gt;"Your scientists were so preoccupied with whether or not they could that they didn't stop to think if they should."&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;Instead of having to figure out &lt;em&gt;whyyy is the padding not working&lt;/em&gt; as you'd expect, you can use tailwind-merge and give hierarchy on how all the various classes take priority.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// button.tsx&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;FC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&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;react&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;twMerge&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;tailwind-merge&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="nx"&gt;styles&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;./button.module.scss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&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;secondary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;children&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ReactNode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FC&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ButtonProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;children&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;baseClasses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;p-4 rounded-lg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;typeClasses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-blue-500 text-white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bg-gray-500 text-black&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;twMerge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baseClasses&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;typeClasses&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assuming a fictitious &lt;code&gt;button.module.scss&lt;/code&gt; containing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="c1"&gt;// button.module.scss&lt;/span&gt;

&lt;span class="nc"&gt;.button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;@apply&lt;/span&gt; &lt;span class="nt"&gt;text-xl&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;The button will eventually have the following classes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'p-4 rounded-lg bg-red-500 underline text-xl text-white'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach eliminates potential conflicts and contradictions and hopefully keeps your elements rendered with fewer clean(er) classes.&lt;/p&gt;

&lt;p&gt;The one caveat of Tailwind Merge, imho, is that you would have to start using it at the beginning of a project; however, nothing prevents you from progressively add it into the codebase.&lt;/p&gt;




&lt;p&gt;Now, what else? Well, there's plenty! &lt;/p&gt;


&lt;h2&gt;
  
  
  Speed it up with component libraries
&lt;/h2&gt;

&lt;p&gt;We all like to keep rebuilding the wheel, as every project proposes different nuances and we just want that button to work &lt;em&gt;exactly&lt;/em&gt; as we had it envisioned. But the key to a successful "I build it my way" is to know when to build and when to borrow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ui.shadcn.com/" rel="noopener noreferrer"&gt;shadcn/ui&lt;/a&gt; offers a great set of components (styled with Tailwind) that you can take as-is and customize all while they already include some accessibility contemplations. It differs from other libraries as it invites you to be hands-on the actual component and it allows you to modify it to your exact needs without having to create extra levels of abstractions for customisation.&lt;/p&gt;

&lt;p&gt;It is worth to note that, like everything, it is not perfect and sometimes you might want to rewrite a couple of things here and there. For example, its class handling proposes a mix of &lt;code&gt;clsx&lt;/code&gt; and &lt;code&gt;twMerge&lt;/code&gt; that might be redundant, as described by &lt;a href="https://medium.com/@pablo.haller" rel="noopener noreferrer"&gt;Pablo Haller&lt;/a&gt; in his article &lt;a href="https://medium.com/@pablo.haller/something-i-dont-like-from-shadcn-ui-3b71c9080a7d" rel="noopener noreferrer"&gt;Something I don’t like from shadcn/ui&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That being said, shadcn/ui is a great way to speed up your work, especially combined with some good Figma prototyping made simple for you by &lt;a href="https://www.figma.com/@skirano" rel="noopener noreferrer"&gt;Pietro Schirano&lt;/a&gt; with their Figma &lt;a href="https://www.figma.com/community/file/1203061493325953101" rel="noopener noreferrer"&gt;@shadcn/ui - Design System&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And while shadcn/ui is a great free solution to implement ready-made-tailwind-styled components, you might want to use a more mature system such as Flowbite.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://flowbite.com/" rel="noopener noreferrer"&gt;Flowbite&lt;/a&gt; (whose main contributor is &lt;a href="https://flowbite.com/blog/author/zoltan/" rel="noopener noreferrer"&gt;Zoltán Szőgyényi&lt;/a&gt;) is a component library that is also built on top of Tailwind CSS. It provides a broader set of UI components that you can easily integrate into your Tailwind projects and it really helps you making everything look professional and curated from the very beginning.&lt;/p&gt;

&lt;p&gt;On top of everything, Flowbite proposes a lot of videos that help you navigate the new ecosystem, as well as a lot of constant updates to their product, which we know is something we desire in a system that we want to implement and hopefully use for a long time.&lt;/p&gt;

&lt;p&gt;If you want to familiarise with a great design system but you're not ready yet to make a monetary commitment, Flowbite is the right resource nonetheless. They offer also a free version of their &lt;a href="https://www.figma.com/community/file/1179442320711977498" rel="noopener noreferrer"&gt;Flowbite Design System&lt;/a&gt;, which can help you speed up your prototyping and design process while keeping high-quality mockups — and eventually figure out if Flowbite is the solution you were looking for.&lt;/p&gt;


&lt;h2&gt;
  
  
  Let's talk about forms
&lt;/h2&gt;

&lt;p&gt;Got no time to make that form pretty? Worry not, because &lt;a href="https://github.com/tailwindlabs/tailwindcss-forms/tree/master?tab=readme-ov-file" rel="noopener noreferrer"&gt;Tailwind Forms&lt;/a&gt; can come to the rescue to style in a consistent manner all your forms!&lt;/p&gt;

&lt;p&gt;It provides base styles for form controls like inputs, text areas, checkboxes, and radio buttons. &lt;/p&gt;

&lt;p&gt;You can simply install the plugin&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @tailwindcss/forms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;add it to your tailwind.config.js&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;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//...&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@tailwindcss/forms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and that's pretty much it! Wanna customise something more? Feel free to add some extra styles to the form elements like you normally would!&lt;/p&gt;

&lt;p&gt;Be sure to check out the &lt;a href="https://github.com/tailwindlabs/tailwindcss-forms/tree/master?tab=readme-ov-file" rel="noopener noreferrer"&gt;Tailwind Forms documentation&lt;/a&gt; and be sure to checkout the &lt;a href="https://tailwindcss-forms.vercel.app/" rel="noopener noreferrer"&gt;Tailwind Form example&lt;/a&gt; they provide!&lt;/p&gt;



&lt;h2&gt;
  
  
  Snippity snippets!
&lt;/h2&gt;

&lt;p&gt;I'd like to end this article by shining some lights on other majestic work that people have done and shared.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F1VqHSzwMvbUCSHeNpRFxT4%2F9eb7ae356355ca3f412c2ae581724f3b%2Ftailwindui.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F1VqHSzwMvbUCSHeNpRFxT4%2F9eb7ae356355ca3f412c2ae581724f3b%2Ftailwindui.png" alt="Tailwind UI Homepage"&gt;&lt;/a&gt;The homepage of &lt;a href="https://tailwindui.com/" rel="noopener noreferrer"&gt;Tailwind UI&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;You can find a ready-made collection of templates in &lt;a href="https://tailwindui.com/components" rel="noopener noreferrer"&gt;Tailwind UI&lt;/a&gt;, developed and curated by the very same creators of Tailwind. It's a nice mature collection of components and templates, with the only downside that it will cost you some money. But hey, quality stuff nevertheless!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F6cDgdFcacIB63GNFTkSpcd%2F351abeabebb69df812e1ab624a62a950%2Ftailwind_snippets.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2F6cDgdFcacIB63GNFTkSpcd%2F351abeabebb69df812e1ab624a62a950%2Ftailwind_snippets.png" alt="Tailwind Snippets"&gt;&lt;/a&gt;The homepage of &lt;a href="https://react-tailwind-snippets.vercel.app/" rel="noopener noreferrer"&gt;Tailwind Snippets&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://react-tailwind-snippets.vercel.app/" rel="noopener noreferrer"&gt;Tailwind Snippets&lt;/a&gt;, as it mentions in their homepage, proposes a collection of UI templates to speed up your UI development using React and Tailwind CSS. Quick and easy to browse, find the elements you need and copy away!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2FaMB4NOWpxJrjqKI9L0Aqq%2Fc370438339aaa99b6c65aead47948375%2Ftailwind_snippets_vscode.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2FaMB4NOWpxJrjqKI9L0Aqq%2Fc370438339aaa99b6c65aead47948375%2Ftailwind_snippets_vscode.png" alt="Tailwind Snippets"&gt;&lt;/a&gt;&lt;a href="https://tws.zarifprogrammer.com/" rel="noopener noreferrer"&gt;Tailwind Snippets&lt;/a&gt; website, but the one of the &lt;a href="https://marketplace.visualstudio.com/items?itemName=Zarifprogrammer.tailwind-snippets" rel="noopener noreferrer"&gt;Tailwind Snippets VSCode plugin&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;With the same name but with a VSCode extension coming along with it, &lt;a href="https://marketplace.visualstudio.com/items?itemName=Zarifprogrammer.tailwind-snippets" rel="noopener noreferrer"&gt;Tailwind Snippets&lt;/a&gt; is a VSCode extension that allows you to take advantage of the numerous snippets available in &lt;a href="https://tws.zarifprogrammer.com/" rel="noopener noreferrer"&gt;Tailwind Snippets&lt;/a&gt; and developed by &lt;a href="https://studio.zarifprogrammer.com/" rel="noopener noreferrer"&gt;ZS Software Studio&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2FKeYdPqQhZnTQFU7gZERvA%2F2fb0ebf91613215023933b52fc93a569%2Ftailwind_components.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimages.ctfassets.net%2Fhzu7wkrk7tly%2FKeYdPqQhZnTQFU7gZERvA%2F2fb0ebf91613215023933b52fc93a569%2Ftailwind_components.png" alt="Tailwind Components"&gt;&lt;/a&gt;&lt;a href="https://tailwindcomponents.com/" rel="noopener noreferrer"&gt;Tailwind Components&lt;/a&gt; website.&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;p&gt;On the same note, you'll find &lt;a href="https://tailwindcomponents.com/" rel="noopener noreferrer"&gt;Tailwind Components&lt;/a&gt; with its community-shared free-to-use components... all the options!&lt;/p&gt;

&lt;p&gt;And these are just a few of the ready-made snippets you can copy away. Do you have a favourite one, or am I missing out on something good? Please share!&lt;/p&gt;




&lt;p&gt;I hope you found some good resources in this article, and that ideally you might have learned a thing or two. If you have any questions or additional tips, drop a comment below!&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources and inspiration
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss" rel="noopener noreferrer"&gt;Tailwind CSS Intellisense&lt;/a&gt; by &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=stivo.tailwind-fold" rel="noopener noreferrer"&gt;Tailwind Fold&lt;/a&gt; by &lt;a href="https://marketplace.visualstudio.com/publishers/stivo" rel="noopener noreferrer"&gt;Stivo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://flaviocopes.com/hiding-classes-in-vs-code/" rel="noopener noreferrer"&gt;Hiding classes in VSCode&lt;/a&gt; by &lt;a href="https://flaviocopes.com/" rel="noopener noreferrer"&gt;Flavio Copes&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.rootstrap.com/blog/how-to-use-module-scss-with-tailwind-in-next-js" rel="noopener noreferrer"&gt;How to Use Module SCSS with Tailwind in Next.js&lt;/a&gt; by Joaquin Collado via &lt;a href="https://www.rootstrap.com/" rel="noopener noreferrer"&gt;Rootstrap&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://chat.openai.com/" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt; prompt:
&lt;code&gt;Can you show me what order would the class list (handled by Tailwind Raw Reorder) have?&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marketplace.visualstudio.com/items?itemName=Trapfether.tailwind-raw-reorder" rel="noopener noreferrer"&gt;Tailwind Raw Reorder&lt;/a&gt; by &lt;a href="https://marketplace.visualstudio.com/publishers/Trapfether" rel="noopener noreferrer"&gt;Andrew Trefethen&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/tailwind-merge" rel="noopener noreferrer"&gt;&lt;code&gt;tailwind-merge&lt;/code&gt; npm package&lt;/a&gt; by &lt;a href="https://github.com/dcastil" rel="noopener noreferrer"&gt;Dany Castillo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ui.shadcn.com/" rel="noopener noreferrer"&gt;shadcn/ui&lt;/a&gt; main website&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/@pablo.haller/something-i-dont-like-from-shadcn-ui-3b71c9080a7d" rel="noopener noreferrer"&gt;Something I don’t like from shadcn/ui&lt;/a&gt; by &lt;a href="https://medium.com/@pablo.haller" rel="noopener noreferrer"&gt;Pablo Haller&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://flowbite.com/" rel="noopener noreferrer"&gt;Flowbite&lt;/a&gt; by &lt;a href="https://flowbite.com/blog/author/zoltan/" rel="noopener noreferrer"&gt;Zoltán Szőgyényi&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.figma.com/community/file/1179442320711977498" rel="noopener noreferrer"&gt;Flowbite Design System&lt;/a&gt; on &lt;a href="https://www.figma.com" rel="noopener noreferrer"&gt;Figma&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/tailwindlabs/tailwindcss-forms/tree/master?tab=readme-ov-file" rel="noopener noreferrer"&gt;Tailwind Forms documentation&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwindui.com/components" rel="noopener noreferrer"&gt;Tailwind UI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://react-tailwind-snippets.vercel.app/" rel="noopener noreferrer"&gt;Tailwind Snippets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tws.zarifprogrammer.com/" rel="noopener noreferrer"&gt;Tailwind Snippets&lt;/a&gt;, the one that offers the &lt;a href="https://marketplace.visualstudio.com/items?itemName=Zarifprogrammer.tailwind-snippets" rel="noopener noreferrer"&gt;Tailwind Snippets VSCode plugin&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwindcomponents.com/" rel="noopener noreferrer"&gt;Tailwind Components&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cover: &lt;a href="https://www.freepik.com/free-ai-image/view-3d-young-school-student_133758575.htm" rel="noopener noreferrer"&gt;3d young school student&lt;/a&gt; by &lt;a href="https://freepik.com" rel="noopener noreferrer"&gt;Freepik&lt;/a&gt;, &lt;a href="https://www.freepik.com/free-vector/flat-abstract-wireframe-background_16133537.htm" rel="noopener noreferrer"&gt;Flat abstract wireframe background&lt;/a&gt; by &lt;a href="https://freepik.com" rel="noopener noreferrer"&gt;Freepik&lt;/a&gt;, Tailwind logotype from &lt;a href="https://tailwindcss.com/brand" rel="noopener noreferrer"&gt;Tailwind Official Brand page&lt;/a&gt;, semi-random coding text generated with &lt;a href="https://carbon.now.sh" rel="noopener noreferrer"&gt;Carbon&lt;/a&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally posted in &lt;a href="https://oh-no.ooo" rel="noopener noreferrer"&gt;oh-no.ooo&lt;/a&gt; (&lt;a href="https://www.oh-no.ooo/articles/level-up-your-tailwind-game" rel="noopener noreferrer"&gt;Level up your Tailwind game&lt;/a&gt;), my personal website.&lt;/p&gt;

</description>
      <category>tailwindcss</category>
      <category>css</category>
      <category>mixin</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
