<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: kingfujing</title>
    <description>The latest articles on DEV Community by kingfujing (@kingfujing).</description>
    <link>https://dev.to/kingfujing</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3992837%2Fe0a2f2c9-59ee-416e-9697-e574407cb3ca.jpeg</url>
      <title>DEV Community: kingfujing</title>
      <link>https://dev.to/kingfujing</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kingfujing"/>
    <language>en</language>
    <item>
      <title>SQL Query Cheat Sheet: Essential Queries and Patterns</title>
      <dc:creator>kingfujing</dc:creator>
      <pubDate>Thu, 12 Nov 2026 02:05:00 +0000</pubDate>
      <link>https://dev.to/kingfujing/sql-query-cheat-sheet-essential-queries-and-patterns-3nda</link>
      <guid>https://dev.to/kingfujing/sql-query-cheat-sheet-essential-queries-and-patterns-3nda</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://devtoolshub.cloud/blog/sql-query-cheat-sheet" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — free, privacy-first online tools for developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;SQL is the language of data. Whether you're pulling records from a Postgres&lt;br&gt;
          database, debugging a slow query in MySQL, or writing analytics queries in&lt;br&gt;
          Snowflake, the fundamentals are the same. This cheat sheet covers everything from&lt;br&gt;
          basic SELECT statements to advanced window functions — with syntax that works&lt;br&gt;
          across most major SQL databases.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Each section includes the syntax, a practical example, and notes on database-specific
      differences where they matter. Bookmark this page and use it as your daily reference
      for writing SQL queries.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚡ Quick Tip&lt;/strong&gt; Use our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;&lt;br&gt;
 JSON Formatter&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 to prettify your JSON query results, and our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/tools/regex-tester" rel="noopener noreferrer"&gt;&lt;br&gt;
 Regex Tester&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 for crafting SQL pattern-matching expressions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. SELECT &amp;amp; FROM
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      The foundation of every SQL query. `SELECT` specifies
      which columns to return, `FROM` specifies the table.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Select all columns&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Select specific columns&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Select with alias&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Select distinct values&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Select with LIMIT (MySQL/Postgres)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Select with TOP (SQL Server)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="no"&gt;TOP&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Select with FETCH (standard SQL / Oracle)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;OFFSET&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;ROWS&lt;/span&gt; &lt;span class="k"&gt;FETCH&lt;/span&gt; &lt;span class="no"&gt;NEXT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;ROWS&lt;/span&gt; &lt;span class="k"&gt;ONLY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. WHERE Clause
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Filter rows based on conditions. The WHERE clause is evaluated row-by-row before
      GROUP BY and aggregate functions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Comparison operators&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;total&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="c1"&gt;-- String matching&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'A%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;-- starts with A&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'%son%'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;-- contains 'son'&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;LIKE&lt;/span&gt; &lt;span class="s1"&gt;'_oe'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;-- exactly 3 chars, ends with 'oe'&lt;/span&gt;

&lt;span class="c1"&gt;-- IN operator&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'shipped'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'delivered'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'pending'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- BETWEEN&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="k"&gt;BETWEEN&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- NULL checks&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="kc"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="kc"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Multiple conditions&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'active'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2024-01-01'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;priority&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'high'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Boolean expressions&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="n"&gt;discontinued&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;category_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ NULL Comparison&lt;/strong&gt; NULL is not equal to anything — not even&lt;br&gt;
 NULL . Use IS NULL&lt;br&gt;
 or IS NOT NULL . Expressions like&lt;br&gt;
 column = NULL will always evaluate to false&lt;br&gt;
 (or unknown in SQL three-valued logic).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. JOINs
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Combine rows from two or more tables based on related columns. Understanding JOINs
      is critical for working with normalized databases.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  INNER JOIN
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Returns rows where there is a match in **both** tables.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Only returns users with at least one order&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  LEFT JOIN
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Returns all rows from the **left** table, with matching rows from the right table. Non-matching right-side columns are `NULL`.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Returns ALL users, even if they have no orders&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  RIGHT JOIN
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Returns all rows from the **right** table, with matching rows from the left table. Less common — usually you can rewrite as a LEFT JOIN by swapping table order.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;
&lt;span class="k"&gt;RIGHT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- All orders, even if user is missing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  FULL OUTER JOIN
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Returns all rows from **both** tables. Missing matches are `NULL` on the opposite side.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;order_id&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;
&lt;span class="k"&gt;FULL&lt;/span&gt; &lt;span class="k"&gt;OUTER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- All users and all orders, matched where possible&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CROSS JOIN
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Cartesian product — every row from table A combined with every row from table B. Use sparingly.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;sizes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;sizes&lt;/span&gt;
&lt;span class="k"&gt;CROSS&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;colors&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Returns size × color combinations&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Self JOIN
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Joining a table to itself — useful for hierarchies (e.g., employees and managers).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;manager_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 JOIN vs WHERE Filtering&lt;/strong&gt; Conditions on the right table in a LEFT JOIN should go in the&lt;br&gt;
 JOIN clause, not the WHERE clause. A condition like&lt;br&gt;
 WHERE o.status = 'active' effectively&lt;br&gt;
 converts a LEFT JOIN to an INNER JOIN because it filters out NULL rows.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  4. GROUP BY &amp;amp; HAVING
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      `GROUP BY` groups rows with the same values, then
      aggregate functions are applied per group. `HAVING`
      filters groups (like WHERE filters rows).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Count users per status&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;COUNT&lt;/span&gt;&lt;span class="cm"&gt;(*) AS user_count
FROM users
GROUP BY status;

-- Multiple grouping columns
SELECT category_id, YEAR(created_at) AS year, COUNT(*)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="nb"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;YEAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Using HAVING (filter groups)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;avg_price&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt;
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="nb"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- HAVING with multiple conditions&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;COUNT&lt;/span&gt;&lt;span class="cm"&gt;(*) AS order_count, SUM(total) AS total_spent
FROM orders
GROUP BY user_id
HAVING COUNT(*)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="nb"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;total_spent&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ WHERE vs HAVING&lt;/strong&gt; WHERE filters rows before grouping.&lt;br&gt;
 HAVING filters groups after aggregation.&lt;br&gt;
 You can use both in the same query:&lt;br&gt;
 WHERE created_at &amp;gt; '2024-01-01'&lt;br&gt;
 (filter rows), then&lt;br&gt;
 HAVING COUNT(*) &amp;gt; 5 (filter groups).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  5. ORDER BY
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Sort results by one or more columns. Sorting is applied last, after GROUP BY and HAVING.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Ascending (default)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Descending&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Multiple sort keys&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Sort by aggregate alias&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;COUNT&lt;/span&gt;&lt;span class="cm"&gt;(*) AS cnt
FROM products
GROUP BY category_id
ORDER BY cnt DESC;

-- Sort by column position (not recommended)
SELECT name, price FROM products ORDER BY 2 DESC;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Subqueries
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Subqueries (nested queries) can appear in SELECT, FROM, WHERE, or HAVING clauses.
      They let you break complex problems into logical steps.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Subquery in WHERE&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;price&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;SELECT&lt;/span&gt; &lt;span class="nb"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Subquery with IN&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Subquery in SELECT (scalar subquery)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="nb"&gt;COUNT&lt;/span&gt;&lt;span class="cm"&gt;(*) FROM orders o WHERE o.user_id = u.id) AS order_count
FROM users u;

-- Subquery in FROM (derived table / subquery as table)
SELECT category, AVG(price) AS avg_price
FROM (
  SELECT p.*, c.name AS category
  FROM products p
  JOIN categories c ON p.category_id = c.id
) AS product_categories
GROUP BY category;

-- Correlated subquery (references outer query)
SELECT p1.name, p1.price, p1.category_id
FROM products p1
WHERE p1.price = (
  SELECT MAX(p2.price)
  FROM products p2
  WHERE p2.category_id = p1.category_id
);
-- Gets the most expensive product in each category
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. Common Functions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Aggregate Functions
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;COUNT(*)&lt;/td&gt;
&lt;td&gt;Count all rows in group&lt;/td&gt;
&lt;td&gt;COUNT(*) AS total&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;COUNT(column)&lt;/td&gt;
&lt;td&gt;Count non-NULL values&lt;/td&gt;
&lt;td&gt;COUNT(email)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;COUNT(DISTINCT col)&lt;/td&gt;
&lt;td&gt;Count unique values&lt;/td&gt;
&lt;td&gt;COUNT(DISTINCT city)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SUM(column)&lt;/td&gt;
&lt;td&gt;Sum of values&lt;/td&gt;
&lt;td&gt;SUM(total) AS revenue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AVG(column)&lt;/td&gt;
&lt;td&gt;Average of values&lt;/td&gt;
&lt;td&gt;AVG(price) AS avg_price&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MIN(column)&lt;/td&gt;
&lt;td&gt;Minimum value&lt;/td&gt;
&lt;td&gt;MIN(created_at)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MAX(column)&lt;/td&gt;
&lt;td&gt;Maximum value&lt;/td&gt;
&lt;td&gt;MAX(score) AS high_score&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  NULL Handling
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;COALESCE(val1, val2, ...)&lt;/td&gt;
&lt;td&gt;Returns first non-NULL value&lt;/td&gt;
&lt;td&gt;COALESCE(phone, email, 'N/A')&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NULLIF(expr1, expr2)&lt;/td&gt;
&lt;td&gt;Returns NULL if equal, else expr1&lt;/td&gt;
&lt;td&gt;NULLIF(price, 0)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IFNULL(expr, default)&lt;/td&gt;
&lt;td&gt;MySQL/ SQLite — replaces NULL&lt;/td&gt;
&lt;td&gt;IFNULL(discount, 0)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NVL(expr, default)&lt;/td&gt;
&lt;td&gt;Oracle — replaces NULL&lt;/td&gt;
&lt;td&gt;NVL(commission, 0)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  String Functions
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CONCAT(a, b, ...)&lt;/td&gt;
&lt;td&gt;Concatenate strings&lt;/td&gt;
&lt;td&gt;CONCAT(first, ' ', last)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;UPPER(str)&lt;/td&gt;
&lt;td&gt;Convert to uppercase&lt;/td&gt;
&lt;td&gt;UPPER(email)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LOWER(str)&lt;/td&gt;
&lt;td&gt;Convert to lowercase&lt;/td&gt;
&lt;td&gt;LOWER(name)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TRIM(str)&lt;/td&gt;
&lt;td&gt;Remove leading/trailing spaces&lt;/td&gt;
&lt;td&gt;TRIM(' hello ')&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SUBSTRING(str, start, len)&lt;/td&gt;
&lt;td&gt;Extract substring&lt;/td&gt;
&lt;td&gt;SUBSTRING(phone, 1, 3)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REPLACE(str, from, to)&lt;/td&gt;
&lt;td&gt;Replace substring&lt;/td&gt;
&lt;td&gt;REPLACE(name, ' ', '_')&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LENGTH(str)&lt;/td&gt;
&lt;td&gt;String length&lt;/td&gt;
&lt;td&gt;LENGTH(description)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Date/Time Functions
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Function&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;NOW() / CURRENT_TIMESTAMP&lt;/td&gt;
&lt;td&gt;Current date and time&lt;/td&gt;
&lt;td&gt;WHERE created_at &amp;lt; NOW()&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CURRENT_DATE&lt;/td&gt;
&lt;td&gt;Current date only&lt;/td&gt;
&lt;td&gt;WHERE date = CURRENT_DATE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DATE_TRUNC(part, date)&lt;/td&gt;
&lt;td&gt;Truncate date to precision&lt;/td&gt;
&lt;td&gt;DATE_TRUNC('month', ts)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EXTRACT(part FROM date)&lt;/td&gt;
&lt;td&gt;Extract a date part&lt;/td&gt;
&lt;td&gt;EXTRACT(YEAR FROM ts)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DATEDIFF(end, start)&lt;/td&gt;
&lt;td&gt;Difference in days&lt;/td&gt;
&lt;td&gt;DATEDIFF('day', start, end)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  8. Window Functions
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Window functions perform calculations across a set of rows related to the current row
      — **without collapsing** the result set like GROUP BY
      does. They are among the most powerful SQL features for analytics.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  ROW_NUMBER, RANK, DENSE_RANK
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- ROW_NUMBER: unique sequential number per partition&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;department_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;department_id&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="k"&gt;DESC&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;rank&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- Within each department, rank employees by salary descending&lt;/span&gt;

&lt;span class="c1"&gt;-- RANK: same values get same rank, next skips numbers&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;RANK&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="k"&gt;DESC&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;rank&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- 3rd place if 2 tied: 100, 95, 95, 90 → ranks 1, 2, 2, 4&lt;/span&gt;

&lt;span class="c1"&gt;-- DENSE_RANK: no gaps in ranking&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;DENSE_RANK&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="k"&gt;DESC&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;dense_rank&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- 100, 95, 95, 90 → ranks 1, 2, 2, 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  LAG and LEAD
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Access data from previous or next rows without self-joins.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- LAG: previous row value&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="kt"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;revenue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;LAG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;revenue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="kt"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;prev_day_revenue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;LAG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;revenue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="kt"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;prev_week_revenue&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;daily_revenue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- LEAD: next row value&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="kt"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;revenue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;LEAD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;revenue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="kt"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;next_day_revenue&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;daily_revenue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Difference from previous value&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;employee_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;LAG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salary&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;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;employee_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;salary_change&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;salaries&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Aggregate Window Functions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Running total&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="kt"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="kt"&gt;date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;running_total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;transactions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Moving average (3-day)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="kt"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;revenue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;revenue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="kt"&gt;date&lt;/span&gt; &lt;span class="k"&gt;ROWS&lt;/span&gt; &lt;span class="k"&gt;BETWEEN&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;PRECEDING&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;CURRENT&lt;/span&gt; &lt;span class="k"&gt;ROW&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;moving_avg_3day&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;daily_revenue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Partitioned aggregates&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
  &lt;span class="n"&gt;department_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;employee_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nb"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;department_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;dept_avg_salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;department_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;diff_from_dept_avg&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Window Function Frame Clause&lt;/strong&gt; The frame clause ( ROWS BETWEEN ... or&lt;br&gt;
 RANGE BETWEEN ... ) defines which rows are included&lt;br&gt;
 in the window. Common frames:&lt;br&gt;
 UNBOUNDED PRECEDING (all previous),&lt;br&gt;
 CURRENT ROW , and&lt;br&gt;
 N FOLLOWING .&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  9. DML: INSERT, UPDATE, DELETE
&lt;/h2&gt;

&lt;h3&gt;
  
  
  INSERT
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Single row&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Alice'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'alice@example.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'active'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Multiple rows&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Widget'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;9.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Gadget'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;24.99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Doohickey'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;14.99&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="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Insert from query&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;archived_orders&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="s1"&gt;'2023-01-01'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  UPDATE
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Simple update&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'inactive'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;last_login&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="s1"&gt;'2024-01-01'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Update multiple columns&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt;
  &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Update with subquery&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;categories&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Clearance'&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;category_id&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="kc"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  DELETE
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Delete specific rows&lt;/span&gt;
&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;logs&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="s1"&gt;'2020-01-01'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Delete all rows (truncate is faster)&lt;/span&gt;
&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;temp_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Delete with subquery&lt;/span&gt;
&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Always Use WHERE in DELETE/UPDATE&lt;/strong&gt; Forgetting the WHERE clause in a DELETE or UPDATE affects all rows .&lt;br&gt;
 When writing destructive queries, first write the matching SELECT to verify which&lt;br&gt;
 rows will be affected.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  10. DDL: CREATE TABLE &amp;amp; Indexes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  CREATE TABLE
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;-- Basic table
CREATE TABLE users &lt;span class="o"&gt;(&lt;/span&gt;
  id SERIAL PRIMARY KEY,
  name VARCHAR&lt;span class="o"&gt;(&lt;/span&gt;100&lt;span class="o"&gt;)&lt;/span&gt; NOT NULL,
  email VARCHAR&lt;span class="o"&gt;(&lt;/span&gt;255&lt;span class="o"&gt;)&lt;/span&gt; UNIQUE NOT NULL,
  status VARCHAR&lt;span class="o"&gt;(&lt;/span&gt;20&lt;span class="o"&gt;)&lt;/span&gt; DEFAULT &lt;span class="s1"&gt;'active'&lt;/span&gt;,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

-- Table with foreign key
CREATE TABLE orders &lt;span class="o"&gt;(&lt;/span&gt;
  id SERIAL PRIMARY KEY,
  user_id INTEGER NOT NULL REFERENCES users&lt;span class="o"&gt;(&lt;/span&gt;id&lt;span class="o"&gt;)&lt;/span&gt;,
  total DECIMAL&lt;span class="o"&gt;(&lt;/span&gt;10, 2&lt;span class="o"&gt;)&lt;/span&gt; NOT NULL CHECK &lt;span class="o"&gt;(&lt;/span&gt;total &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; 0&lt;span class="o"&gt;)&lt;/span&gt;,
  status VARCHAR&lt;span class="o"&gt;(&lt;/span&gt;20&lt;span class="o"&gt;)&lt;/span&gt; DEFAULT &lt;span class="s1"&gt;'pending'&lt;/span&gt;,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

-- Table with composite primary key
CREATE TABLE order_items &lt;span class="o"&gt;(&lt;/span&gt;
  order_id INTEGER REFERENCES orders&lt;span class="o"&gt;(&lt;/span&gt;id&lt;span class="o"&gt;)&lt;/span&gt;,
  product_id INTEGER REFERENCES products&lt;span class="o"&gt;(&lt;/span&gt;id&lt;span class="o"&gt;)&lt;/span&gt;,
  quantity INTEGER NOT NULL,
  unit_price DECIMAL&lt;span class="o"&gt;(&lt;/span&gt;10, 2&lt;span class="o"&gt;)&lt;/span&gt; NOT NULL,
  PRIMARY KEY &lt;span class="o"&gt;(&lt;/span&gt;order_id, product_id&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Indexes
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Indexes speed up queries at the cost of slower writes. Use them on columns used
      in WHERE, JOIN, and ORDER BY.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Single column index&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_users_email&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="nf"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Composite index (column order matters!)&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_orders_user_status&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="nf"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Unique index&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_products_sku&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="nf"&gt;products&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sku&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Partial index (Postgres)&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_active_users&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="nf"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'active'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Full-text index (MySQL/Postgres)&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_products_name&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="no"&gt;GIN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;to_tsvector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'english'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&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;-- Drop index&lt;/span&gt;
&lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_users_email&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  11. Query Optimization Tips
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tip&lt;/th&gt;
&lt;th&gt;Explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Avoid SELECT *&lt;/td&gt;
&lt;td&gt;Only fetch columns you need. Reduces I/O and network overhead.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use EXISTS vs IN&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;EXISTS&lt;/code&gt; stops scanning as soon as a match is found. &lt;code&gt;IN&lt;/code&gt; materializes the entire subquery result.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Index JOIN columns&lt;/td&gt;
&lt;td&gt;Columns used in &lt;code&gt;ON&lt;/code&gt; and &lt;code&gt;WHERE&lt;/code&gt; clauses should be indexed.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Avoid functions in WHERE&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;WHERE YEAR(created_at) = 2024&lt;/code&gt; prevents index use. Use &lt;code&gt;WHERE created_at &amp;gt;= '2024-01-01' AND created_at &amp;lt; '2025-01-01'&lt;/code&gt; instead.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use UNION ALL instead of UNION&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;UNION&lt;/code&gt; deduplicates (extra sort). &lt;code&gt;UNION ALL&lt;/code&gt; just appends — use it when you know there are no duplicates.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use EXPLAIN&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;EXPLAIN ANALYZE SELECT ...&lt;/code&gt; shows the query plan and actual execution time. Always check it for slow queries.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Limit pagination depth&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;OFFSET 10000 LIMIT 10&lt;/code&gt; still scans 10010 rows. Use keyset pagination (&lt;code&gt;WHERE id &amp;gt; last_id LIMIT 10&lt;/code&gt;) for deep pages.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use materialized views&lt;/td&gt;
&lt;td&gt;For expensive aggregations that don't change often, precompute with &lt;code&gt;CREATE MATERIALIZED VIEW&lt;/code&gt; and refresh periodically.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  12. Common Table Expressions (CTEs)
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      CTEs let you name a subquery and reference it like a table. They improve readability
      and enable recursive queries.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Basic CTE&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;high_value_orders&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_spent&lt;/span&gt;
  &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'delivered'&lt;/span&gt;
  &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;
  &lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="nb"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total_spent&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;high_value_orders&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Recursive CTE (hierarchy)&lt;/span&gt;
&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="no"&gt;RECURSIVE&lt;/span&gt; &lt;span class="n"&gt;org_chart&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="c1"&gt;-- Base: top-level managers&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;manager_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;
  &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
  &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;manager_id&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="kc"&gt;NULL&lt;/span&gt;

  &lt;span class="k"&gt;UNION&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt;

  &lt;span class="c1"&gt;-- Recursive: direct reports&lt;/span&gt;
  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;manager_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;oc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
  &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;org_chart&lt;/span&gt; &lt;span class="n"&gt;oc&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;manager_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;oc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;org_chart&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  13. Database-Specific Syntax
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;PostgreSQL&lt;/th&gt;
&lt;th&gt;MySQL&lt;/th&gt;
&lt;th&gt;SQL Server&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Auto-increment&lt;/td&gt;
&lt;td&gt;SERIAL / IDENTITY&lt;/td&gt;
&lt;td&gt;AUTO_INCREMENT&lt;/td&gt;
&lt;td&gt;IDENTITY(1,1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ILIKE&lt;/td&gt;
&lt;td&gt;ILIKE (case-insensitive)&lt;/td&gt;
&lt;td&gt;LIKE (case-insensitive by default)&lt;/td&gt;
&lt;td&gt;LIKE (case-insensitive based on collation)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LIMIT&lt;/td&gt;
&lt;td&gt;LIMIT 10 OFFSET 20&lt;/td&gt;
&lt;td&gt;LIMIT 10 OFFSET 20&lt;/td&gt;
&lt;td&gt;OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;String concat&lt;/td&gt;
&lt;td&gt;\&lt;/td&gt;
&lt;td&gt;\&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Upsert&lt;/td&gt;
&lt;td&gt;ON CONFLICT DO UPDATE&lt;/td&gt;
&lt;td&gt;ON DUPLICATE KEY UPDATE&lt;/td&gt;
&lt;td&gt;MERGE&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Common Mistakes &amp;amp; How to Avoid Them
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      These five mistakes cause most of the slow queries and wrong results&lt;br&gt;
      I've debugged in production. Each one has a simple fix once you&lt;br&gt;
      know what to look for.
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  -
    **Comparing to NULL with `=`.**
    `WHERE email = NULL` returns zero rows
    because NULL comparisons evaluate to UNKNOWN, not TRUE. Always use
    `IS NULL` / `IS NOT NULL`
    — and remember that `NULL &amp;amp;lt;&amp;amp;gt; 'x'`
    also excludes NULL rows.


  -
    **Using `SELECT *` in production code.**
    It pulls every column, wasting I/O and bandwidth, and silently breaks when
    someone adds a column. List columns explicitly — it also makes your
    application's data contract visible in the query itself.


  -
    **The N+1 query trap.**
    Fetching a list of users, then running one query per user inside a loop,
    is the classic ORM performance killer. Replace it with a single JOIN or an
    `IN` subquery:
    `SELECT * FROM orders WHERE user_id IN (SELECT id FROM users WHERE plan = 'pro')`.


  -
    **Wrapping indexed columns in functions.**
    `WHERE YEAR(created_at) = 2024` forces a full
    scan because the index stores raw values, not function results. Use a range
    predicate instead:
    `created_at &amp;amp;gt;= '2024-01-01' AND created_at &amp;amp;lt; '2025-01-01'`.


  -
    **Deep OFFSET pagination.**
    `OFFSET 100000 LIMIT 50` still reads and
    discards 100,000 rows. Use keyset pagination —
    `WHERE id &amp;amp;gt; last_seen_id ORDER BY id LIMIT 50`
    — which stays fast no matter how deep you go.
&lt;/code&gt;&lt;/pre&gt;

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

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Frequently Asked Questions&lt;br&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What's the difference between INNER JOIN and LEFT JOIN?
&lt;/h3&gt;

&lt;p&gt;INNER JOIN returns only rows that have&lt;br&gt;
                matches in both tables. LEFT JOIN returns&lt;br&gt;
                every row from the left table, filling unmatched right-side columns with&lt;br&gt;
                NULL. If your result is missing rows, you&lt;br&gt;
                probably need a LEFT JOIN; if you're seeing duplicate rows, the&lt;br&gt;
                "one" side has multiple matches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is my query slow, and how do I fix it?
&lt;/h3&gt;

&lt;p&gt;Start with EXPLAIN ANALYZE SELECT ... and&lt;br&gt;
                look for sequential scans on large tables — add an index on the columns&lt;br&gt;
                used in WHERE and&lt;br&gt;
                JOIN. Avoid SELECT *,&lt;br&gt;
                avoid functions around indexed columns, and prefer&lt;br&gt;
                EXISTS over&lt;br&gt;
                IN for large subqueries.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the difference between WHERE and HAVING?
&lt;/h3&gt;

&lt;p&gt;WHERE filters individual rows&lt;br&gt;
                before grouping; HAVING filters&lt;br&gt;
                groups after aggregation. That's why&lt;br&gt;
                WHERE can't reference&lt;br&gt;
                SUM() or COUNT(),&lt;br&gt;
                but HAVING can. Use&lt;br&gt;
                WHERE status = 'paid' to drop rows,&lt;br&gt;
                and HAVING SUM(total) &amp;gt; 100 to drop groups.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do COUNT(*) and COUNT(column) give different results?
&lt;/h3&gt;

&lt;p&gt;COUNT(*) counts every row, including rows&lt;br&gt;
                with NULLs. COUNT(column) counts only&lt;br&gt;
                non-NULL values in that column. If the two numbers differ, your column&lt;br&gt;
                contains NULLs — which is often the real signal you're looking for.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I avoid the N+1 query problem?
&lt;/h3&gt;

&lt;p&gt;Replace loop-based per-row queries with a single JOIN or an&lt;br&gt;
                IN subquery. Instead of querying orders&lt;br&gt;
                once per user, fetch them all at once:&lt;br&gt;
                SELECT * FROM orders WHERE user_id IN (SELECT id FROM users WHERE plan = 'pro').&lt;br&gt;
                In ORMs, use eager loading (selectinload in&lt;br&gt;
                SQLAlchemy, includes in Rails/EF) rather&lt;br&gt;
                than lazy loading.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🔍 Related Resources&lt;/strong&gt; Check out our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/blog/timestamp-cheat-sheet" rel="noopener noreferrer"&gt;&lt;br&gt;
 Unix Timestamp Cheat Sheet&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 for working with dates across SQL databases, and our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;&lt;br&gt;
 JSON Formatter&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 for visualizing query results.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>sql</category>
      <category>database</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>JavaScript Array Methods Cheat Sheet: Every Method with Examples</title>
      <dc:creator>kingfujing</dc:creator>
      <pubDate>Thu, 12 Nov 2026 02:03:54 +0000</pubDate>
      <link>https://dev.to/kingfujing/javascript-array-methods-cheat-sheet-every-method-with-examples-3j72</link>
      <guid>https://dev.to/kingfujing/javascript-array-methods-cheat-sheet-every-method-with-examples-3j72</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://devtoolshub.cloud/blog/javascript-array-methods-cheat-sheet" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — free, privacy-first online tools for developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;JavaScript arrays are everywhere. Whether you're transforming API responses,&lt;br&gt;
          filtering user input, or building complex data pipelines, array methods are the&lt;br&gt;
          tools you reach for daily. But with over 30 methods on&lt;br&gt;
          &lt;code&gt;Array.prototype&lt;/code&gt;, it's easy to lose track of&lt;br&gt;
          which method does what, what it returns, and whether it mutates the original array.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      This cheat sheet covers every major array method — from the classics like
      `push()` and `map()`
      to the newest ES2023 additions like
      `toSorted()`,
      `toReversed()`, and
      `with()`. Methods are grouped by category so you
      can quickly find what you need.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚡ Quick Tip&lt;/strong&gt; Use our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;&lt;br&gt;
 JSON Formatter&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 to inspect API responses that contain arrays, and our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/tools/base64" rel="noopener noreferrer"&gt;&lt;br&gt;
 Base64 Encoder/Decoder&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 for decoding token payloads that use array-like structures.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Quick Legend
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Throughout this guide, each method table includes the following columns:




      - **Method** — The method name and its parameters

      - **Description** — What the method does

      - **Returns** — The return value type

      - **Mutates?** — Whether it modifies the original array

      - **Example** — A concise code snippet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  1. Mutator Methods
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Mutator methods **change the original array**.
      Use them when you want to modify data in place. Be careful — these can lead to
      unintended side effects if referenced elsewhere in your code.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Adding &amp;amp; Removing Elements
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Returns&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;push(el1, ..., elN)&lt;/td&gt;
&lt;td&gt;New &lt;code&gt;length&lt;/code&gt; of array&lt;/td&gt;
&lt;td&gt;arr.push(4) // arr → [1,2,3,4]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pop()&lt;/td&gt;
&lt;td&gt;Removed element (or &lt;code&gt;undefined&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;arr.pop() // returns 3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;unshift(el1, ..., elN)&lt;/td&gt;
&lt;td&gt;New &lt;code&gt;length&lt;/code&gt; of array&lt;/td&gt;
&lt;td&gt;arr.unshift(0) // arr → [0,1,2,3]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;shift()&lt;/td&gt;
&lt;td&gt;Removed element (or &lt;code&gt;undefined&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;arr.shift() // returns 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;splice(start, deleteCount, ...items)&lt;/td&gt;
&lt;td&gt;Array of removed elements&lt;/td&gt;
&lt;td&gt;arr.splice(1, 0, 'a')&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;fill(value, start?, end?)&lt;/td&gt;
&lt;td&gt;Modified array (&lt;code&gt;this&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;arr.fill(0, 1, 3)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;copyWithin(target, start, end?)&lt;/td&gt;
&lt;td&gt;Modified array (&lt;code&gt;this&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;arr.copyWithin(0, 2)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Sorting &amp;amp; Reversing
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Returns&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;sort(compareFn?)&lt;/td&gt;
&lt;td&gt;Modified array (&lt;code&gt;this&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;arr.sort((a,b) =&amp;gt; a - b)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;reverse()&lt;/td&gt;
&lt;td&gt;Modified array (&lt;code&gt;this&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;arr.reverse()&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ sort() Gotcha&lt;/strong&gt; Without a compare function, sort() converts&lt;br&gt;
 elements to strings and sorts lexicographically.&lt;br&gt;
 [10, 2, 1].sort() gives&lt;br&gt;
 [1, 10, 2] . Always provide a compare function&lt;br&gt;
 for numeric sorting.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  2. Accessor Methods
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Accessor methods **do not mutate** the original
      array. They return a new array or value. These are generally safer and more
      predictable — prefer them over mutators when you don't need in-place modification.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Creating New Arrays
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Returns&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;concat(arr2, ..., arrN)&lt;/td&gt;
&lt;td&gt;New concatenated array&lt;/td&gt;
&lt;td&gt;[1].concat([2, 3]) // [1,2,3]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;slice(start?, end?)&lt;/td&gt;
&lt;td&gt;New shallow-copied array&lt;/td&gt;
&lt;td&gt;arr.slice(1, 3)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;flat(depth?)&lt;/td&gt;
&lt;td&gt;New flattened array&lt;/td&gt;
&lt;td&gt;[[1],[2,[3]]].flat(2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;flatMap(fn)&lt;/td&gt;
&lt;td&gt;New flattened array (depth 1)&lt;/td&gt;
&lt;td&gt;arr.flatMap(x =&amp;gt; [x, x*2])&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;join(separator?)&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;arr.join(', ')&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toString()&lt;/td&gt;
&lt;td&gt;Comma-separated string&lt;/td&gt;
&lt;td&gt;arr.toString()&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toLocaleString()&lt;/td&gt;
&lt;td&gt;Localized string&lt;/td&gt;
&lt;td&gt;arr.toLocaleString()&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Searching &amp;amp; Checking
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Returns&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;indexOf(el, fromIndex?)&lt;/td&gt;
&lt;td&gt;First index, or &lt;code&gt;-1&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;[1,2,3].indexOf(2) // 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;lastIndexOf(el, fromIndex?)&lt;/td&gt;
&lt;td&gt;Last index, or &lt;code&gt;-1&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;[1,2,1].lastIndexOf(1) // 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;includes(el, fromIndex?)&lt;/td&gt;
&lt;td&gt;Boolean&lt;/td&gt;
&lt;td&gt;[1,2,3].includes(2) // true&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;find(fn)&lt;/td&gt;
&lt;td&gt;First matching element, or &lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;arr.find(x =&amp;gt; x &amp;gt; 2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;findIndex(fn)&lt;/td&gt;
&lt;td&gt;Index of first match, or &lt;code&gt;-1&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;arr.findIndex(x =&amp;gt; x &amp;gt; 2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;findLast(fn)&lt;/td&gt;
&lt;td&gt;Last matching element, or &lt;code&gt;undefined&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;arr.findLast(x =&amp;gt; x &amp;gt; 2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;findLastIndex(fn)&lt;/td&gt;
&lt;td&gt;Index of last match, or &lt;code&gt;-1&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;arr.findLastIndex(x =&amp;gt; x &amp;gt; 2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;some(fn)&lt;/td&gt;
&lt;td&gt;Boolean&lt;/td&gt;
&lt;td&gt;arr.some(x =&amp;gt; x &amp;gt; 2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;every(fn)&lt;/td&gt;
&lt;td&gt;Boolean&lt;/td&gt;
&lt;td&gt;arr.every(x =&amp;gt; x &amp;gt; 0)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  3. Iterator Methods
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Iterator methods loop over the array and execute a callback. They are the workhorses
      of functional JavaScript. All iterator methods return a new value — they never mutate
      the original array.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Returns&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;forEach(fn)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;undefined&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;arr.forEach(x =&amp;gt; console.log(x))&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;map(fn)&lt;/td&gt;
&lt;td&gt;New array (same length)&lt;/td&gt;
&lt;td&gt;arr.map(x =&amp;gt; x * 2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;filter(fn)&lt;/td&gt;
&lt;td&gt;New array (filtered)&lt;/td&gt;
&lt;td&gt;arr.filter(x =&amp;gt; x &amp;gt; 2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;reduce(fn, initial?)&lt;/td&gt;
&lt;td&gt;Accumulated value (any type)&lt;/td&gt;
&lt;td&gt;arr.reduce((a,b) =&amp;gt; a+b, 0)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;reduceRight(fn, initial?)&lt;/td&gt;
&lt;td&gt;Accumulated value (right-to-left)&lt;/td&gt;
&lt;td&gt;arr.reduceRight((a,b)=&amp;gt;a+b)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Chaining Pattern&lt;/strong&gt; Because most iterator and accessor methods return new arrays, you can chain them:&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="n"&gt;arr&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="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&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="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&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="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. ES2023: The New Wave
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      The 2023 update to ECMAScript introduced three new array methods that return
      ** new arrays** instead of mutating in place.
      These are the non-mutating alternatives to `sort()`,
      `reverse()`, and bracket assignment.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Returns&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;toSorted(compareFn?)&lt;/td&gt;
&lt;td&gt;New sorted array&lt;/td&gt;
&lt;td&gt;arr.toSorted() // arr unchanged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toReversed()&lt;/td&gt;
&lt;td&gt;New reversed array&lt;/td&gt;
&lt;td&gt;arr.toReversed() // arr unchanged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;with(index, value)&lt;/td&gt;
&lt;td&gt;New array with element replaced&lt;/td&gt;
&lt;td&gt;arr.with(1, 99)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;toSpliced(start, deleteCount?, ...items)&lt;/td&gt;
&lt;td&gt;New array with splice applied&lt;/td&gt;
&lt;td&gt;arr.toSpliced(1, 1, 42)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 Immutable Arrays&lt;/strong&gt; The ES2023 methods make it easy to work immutably. Instead of arr.sort() which mutates, use arr.toSorted() which returns a copy. This is especially useful in React and Redux where immutability is required.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  5. Static Methods
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      These are methods on the `Array` constructor itself,
      not on instances.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Returns&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Array.from(arrayLike, mapFn?)&lt;/td&gt;
&lt;td&gt;New array from iterable/array-like&lt;/td&gt;
&lt;td&gt;Array.from('abc') // ['a','b','c']&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Array.of(...items)&lt;/td&gt;
&lt;td&gt;New array from arguments&lt;/td&gt;
&lt;td&gt;Array.of(1, 2, 3)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Array.isArray(value)&lt;/td&gt;
&lt;td&gt;Boolean&lt;/td&gt;
&lt;td&gt;Array.isArray([]) // true&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  6. Practical Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Removing Duplicates
&lt;/h3&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="n"&gt;arr&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;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;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="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;unique&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="p"&gt;.&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arr&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;// [1, 2, 3, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Grouping Objects by Property
&lt;/h3&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="n"&gt;users&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="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="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;grouped&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;role&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="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;acc&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="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deep Flattening
&lt;/h3&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="n"&gt;nested&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="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="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="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="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="n"&gt;nested&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;flat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// [1, 2, 3, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Safe Sorting (Immutably)
&lt;/h3&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="n"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&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;1&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;1&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="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;sorted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toSorted&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// sorted = [1, 1, 3, 4, 5]&lt;/span&gt;
&lt;span class="c1"&gt;// arr = [3, 1, 4, 1, 5] (unchanged!)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. Performance Notes
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      -
        **push/pop** are O(1) — fastest way to add/remove from end.


      -
        **shift/unshift** are O(n) — they re-index all elements.


      -
        **splice** is O(n) in worst case due to re-indexing.


      -
        **filter/map** create new arrays — chaining many of them uses more memory. For performance-critical paths, consider a single `reduce()` or a loop.


      -
        **flat(Infinity)** is convenient but slow for deeply nested arrays. Use iterative flattening for large datasets.


      -
        **sort()** uses Timsort (O(n log n)) and is stable as of ES2019.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  8. Quick Reference Table
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      All methods at a glance. **M** = Mutator,
      **A** = Accessor,
      **I** = Iterator.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cat&lt;/th&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Returns&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;push()&lt;/td&gt;
&lt;td&gt;New length&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;pop()&lt;/td&gt;
&lt;td&gt;Removed element&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;unshift()&lt;/td&gt;
&lt;td&gt;New length&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;shift()&lt;/td&gt;
&lt;td&gt;Removed element&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;splice()&lt;/td&gt;
&lt;td&gt;Removed elements array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;sort()&lt;/td&gt;
&lt;td&gt;Modified array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;reverse()&lt;/td&gt;
&lt;td&gt;Modified array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;fill()&lt;/td&gt;
&lt;td&gt;Modified array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;M&lt;/td&gt;
&lt;td&gt;copyWithin()&lt;/td&gt;
&lt;td&gt;Modified array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;concat()&lt;/td&gt;
&lt;td&gt;New array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;slice()&lt;/td&gt;
&lt;td&gt;New array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;flat()&lt;/td&gt;
&lt;td&gt;New array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;flatMap()&lt;/td&gt;
&lt;td&gt;New array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;join()&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;indexOf()&lt;/td&gt;
&lt;td&gt;Index or -1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;includes()&lt;/td&gt;
&lt;td&gt;Boolean&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;find()&lt;/td&gt;
&lt;td&gt;Element or undefined&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;findIndex()&lt;/td&gt;
&lt;td&gt;Index or -1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;some()&lt;/td&gt;
&lt;td&gt;Boolean&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;every()&lt;/td&gt;
&lt;td&gt;Boolean&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;I&lt;/td&gt;
&lt;td&gt;forEach()&lt;/td&gt;
&lt;td&gt;undefined&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;I&lt;/td&gt;
&lt;td&gt;map()&lt;/td&gt;
&lt;td&gt;New array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;I&lt;/td&gt;
&lt;td&gt;filter()&lt;/td&gt;
&lt;td&gt;New array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;I&lt;/td&gt;
&lt;td&gt;reduce()&lt;/td&gt;
&lt;td&gt;Accumulated value&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;toSorted()&lt;/td&gt;
&lt;td&gt;New array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;toReversed()&lt;/td&gt;
&lt;td&gt;New array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;with()&lt;/td&gt;
&lt;td&gt;New array&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;toSpliced()&lt;/td&gt;
&lt;td&gt;New array&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Browser Support
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      All methods covered here are well-supported in modern browsers:




      -
        **ES2023 methods** (toSorted, toReversed, with, toSpliced): Chrome 110+, Firefox 115+, Safari 16.4+, Node 20+


      -
        **ES2019+ methods** (flat, flatMap): Chrome 69+, Firefox 62+, Safari 12+, Node 11+


      -
        **All others**: Supported everywhere including IE9+ (with polyfills for `find`, `findIndex`)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Common Mistakes &amp;amp; How to Avoid Them
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Even experienced developers trip over these array method gotchas. Here are the five
      most common pitfalls and how to dodge them.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  1. Forgetting That sort() Sorts Strings by Default
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      `sort()` converts every element to a string before
      comparing, so `[10, 2, 1].sort()` returns
      `[1, 10, 2]` — not the numeric order you expected.
      Always pass a comparator for numbers:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// [1, 2, 10]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Mutating an Array While Iterating Over It
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Calling &lt;code&gt;splice()&lt;/code&gt; inside a&lt;br&gt;
      &lt;code&gt;forEach()&lt;/code&gt; loop shifts the indexes of every remaining&lt;br&gt;
      element, which causes items to be silently skipped. Instead of removing elements in&lt;br&gt;
      place, build a new array with &lt;code&gt;filter()&lt;/code&gt; — it is safer&lt;br&gt;
      and easier to reason about.&lt;br&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
&lt;br&gt;
  &lt;br&gt;
  

&lt;ol&gt;
&lt;li&gt;Using map() for Side Effects
&lt;/li&gt;
&lt;/ol&gt;
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      &lt;code&gt;map()&lt;/code&gt; exists to transform data and always returns a
  new array. If you only need to run side effects like logging or DOM updates, use
  &lt;code&gt;forEach()&lt;/code&gt; instead. Calling
  &lt;code&gt;map()&lt;/code&gt; and discarding its return value allocates an
  unused array and signals the wrong intent to readers.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;


&lt;/h3&gt;
&lt;li&gt;filter(Boolean) Silently Drops Falsy Values

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      &lt;code&gt;filter(Boolean)&lt;/code&gt; is a popular one-liner, but it also
  removes &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;""&lt;/code&gt;, and
  &lt;code&gt;NaN&lt;/code&gt;. When those values are meaningful data, use an
  explicit predicate such as
  &lt;code&gt;x =&amp;amp;gt; x !== null &amp;amp;amp;&amp;amp;amp; x !== undefined&lt;/code&gt;.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;


&lt;/h3&gt;
&lt;/li&gt;
&lt;li&gt;map() Skips Holes in Sparse Arrays

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      &lt;code&gt;Array(3).map(x =&amp;amp;gt; 1)&lt;/code&gt; returns an array of empty
  holes, not &lt;code&gt;[1, 1, 1]&lt;/code&gt;. Create a dense array first with
  &lt;code&gt;Array.from()&lt;/code&gt; or
  &lt;code&gt;[...Array(3)]&lt;/code&gt; before mapping over it.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;


Frequently Asked Questions
&lt;/h2&gt;
&lt;h3&gt;


What is the difference between map() and forEach()?
&lt;/h3&gt;
&lt;/li&gt;


&lt;p&gt;map() builds and returns a new array with the&lt;br&gt;
                same length, transformed by the callback. forEach()&lt;br&gt;
                runs the callback for side effects and returns undefined.&lt;br&gt;
                Use map() when you need the transformed result,&lt;br&gt;
                and forEach() when you only need to perform an&lt;br&gt;
                action. Neither can be stopped early with break —&lt;br&gt;
                use a for...of loop if you need early exit.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I remove duplicates from an array?
&lt;/h3&gt;

&lt;p&gt;The simplest approach is to spread a Set:&lt;br&gt;
                [...new Set(arr)]. This preserves insertion&lt;br&gt;
                order and works for primitives. For arrays of objects, dedupe by a key with a&lt;br&gt;
                Map or a Set of&lt;br&gt;
                ids instead of relying on reference equality.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between slice() and splice()?
&lt;/h3&gt;

&lt;p&gt;slice(start, end) returns a new array containing&lt;br&gt;
                a copy of a portion of the original, without modifying it.&lt;br&gt;
                splice(start, deleteCount, ...items) removes or&lt;br&gt;
                replaces elements in the original array and returns the removed elements.&lt;br&gt;
                Remember: slice copies, splice mutates.&lt;br&gt;
                If you need the non-mutating version of splice, use&lt;br&gt;
                toSpliced().&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does sort() return an unexpected order for numbers?
&lt;/h3&gt;

&lt;p&gt;The default sort() converts elements to strings&lt;br&gt;
                and compares them lexicographically, so 10 comes&lt;br&gt;
                before 2. Pass a numeric comparator like&lt;br&gt;
                (a, b) =&amp;gt; a - b to sort numbers correctly, or&lt;br&gt;
                use toSorted() when you want to keep the original&lt;br&gt;
                array unchanged.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I check if an array contains a value?
&lt;/h3&gt;

&lt;p&gt;Use includes(value) for a simple boolean check,&lt;br&gt;
                or indexOf(value) when you also need the position.&lt;br&gt;
                Both use strict equality, so neither can find NaN —&lt;br&gt;
                use some(x =&amp;gt; Number.isNaN(x)) for that case,&lt;br&gt;
                and find() with a predicate when searching for&lt;br&gt;
                objects by property.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🔍 Related Resources&lt;/strong&gt; Check out our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;&lt;br&gt;
 JSON Formatter&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 and&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/tools/base64" rel="noopener noreferrer"&gt;&lt;br&gt;
 Base64 Encoder/Decoder&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 for more dev tools. Also read our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/blog/json-formatting-101" rel="noopener noreferrer"&gt;&lt;br&gt;
 JSON Formatting Guide&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 for data debugging tips.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>HTTP Status Codes Cheat Sheet: Every Code Explained</title>
      <dc:creator>kingfujing</dc:creator>
      <pubDate>Thu, 12 Nov 2026 02:02:48 +0000</pubDate>
      <link>https://dev.to/kingfujing/http-status-codes-cheat-sheet-every-code-explained-1n8b</link>
      <guid>https://dev.to/kingfujing/http-status-codes-cheat-sheet-every-code-explained-1n8b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://devtoolshub.cloud/blog/http-status-codes-cheat-sheet" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — free, privacy-first online tools for developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every web developer encounters HTTP status codes daily. From successful&lt;br&gt;
          &lt;code&gt;200 OK&lt;/code&gt; responses to mysterious&lt;br&gt;
          &lt;code&gt;418 I'm a Teapot&lt;/code&gt; — understanding what each code&lt;br&gt;
          means is essential for debugging APIs, configuring servers, and building robust&lt;br&gt;
          applications.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      This cheat sheet covers every standard HTTP status code from **100** to
      **511**, grouped by category. Use it as a quick reference whenever you
      encounter an unfamiliar response code.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🔍 Quick Tip&lt;/strong&gt; Use our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;&lt;br&gt;
 JSON Formatter&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 to prettify API error responses, and our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/tools/base64" rel="noopener noreferrer"&gt;&lt;br&gt;
 Base64 Encoder/Decoder&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 to decode token-based auth errors.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1xx Informational Responses
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      These codes indicate that the server has received the request headers and the client
      should continue sending the request body. They are provisional responses — the client
      should wait for a final response.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;Continue&lt;/td&gt;
&lt;td&gt;Server received headers, client should send body&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;Switching Protocols&lt;/td&gt;
&lt;td&gt;Server is switching to the protocol requested in Upgrade header (e.g., WebSocket)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;Processing&lt;/td&gt;
&lt;td&gt;Server has received and is processing request, but no response yet (WebDAV)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;Early Hints&lt;/td&gt;
&lt;td&gt;Server can send some response headers before final response (for preloading)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  2xx Success Responses
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      The request was successfully received, understood, and accepted. These are the codes
      every developer loves to see.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;OK&lt;/td&gt;
&lt;td&gt;Standard success response for GET, PUT, PATCH, and POST requests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;201&lt;/td&gt;
&lt;td&gt;Created&lt;/td&gt;
&lt;td&gt;Resource was successfully created (typically after POST/PUT). Include Location header&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;202&lt;/td&gt;
&lt;td&gt;Accepted&lt;/td&gt;
&lt;td&gt;Request accepted but not yet processed (async processing)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;203&lt;/td&gt;
&lt;td&gt;Non-Authoritative Info&lt;/td&gt;
&lt;td&gt;Returned metadata is from a third-party copy, not the origin server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;204&lt;/td&gt;
&lt;td&gt;No Content&lt;/td&gt;
&lt;td&gt;Request succeeded but no content to return (DELETE, or PUT saving unchanged data)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;205&lt;/td&gt;
&lt;td&gt;Reset Content&lt;/td&gt;
&lt;td&gt;Server fulfilled request, user agent should reset the document view&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;206&lt;/td&gt;
&lt;td&gt;Partial Content&lt;/td&gt;
&lt;td&gt;Server is delivering only part of the resource (range requests, video streaming)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;207&lt;/td&gt;
&lt;td&gt;Multi-Status&lt;/td&gt;
&lt;td&gt;Multiple status codes for multiple operations (WebDAV)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;208&lt;/td&gt;
&lt;td&gt;Already Reported&lt;/td&gt;
&lt;td&gt;Members of a DAV binding have already been enumerated (WebDAV)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;226&lt;/td&gt;
&lt;td&gt;IM Used&lt;/td&gt;
&lt;td&gt;Server fulfilled GET request using instance manipulations&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  3xx Redirection Responses
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      The client must take additional action to complete the request. Usually means the
      resource has moved or the request needs different treatment.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;Multiple Choices&lt;/td&gt;
&lt;td&gt;Multiple possible representations; user or agent should choose one&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;301&lt;/td&gt;
&lt;td&gt;Moved Permanently&lt;/td&gt;
&lt;td&gt;Resource permanently moved to new URL. Browsers cache this redirect. Update bookmarks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;302&lt;/td&gt;
&lt;td&gt;Found&lt;/td&gt;
&lt;td&gt;Resource temporarily found at different URI. Use for temporary redirects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;303&lt;/td&gt;
&lt;td&gt;See Other&lt;/td&gt;
&lt;td&gt;Response to POST can be found at another URI (use GET to retrieve)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;304&lt;/td&gt;
&lt;td&gt;Not Modified&lt;/td&gt;
&lt;td&gt;Cached version is still valid (conditional GET using If-Modified-Since / ETag)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;305&lt;/td&gt;
&lt;td&gt;Use Proxy&lt;/td&gt;
&lt;td&gt;Requested resource must be accessed through a proxy (deprecated)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;306&lt;/td&gt;
&lt;td&gt;Switch Proxy&lt;/td&gt;
&lt;td&gt;No longer used. Originally meant "subsequent requests should use specified proxy"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;307&lt;/td&gt;
&lt;td&gt;Temporary Redirect&lt;/td&gt;
&lt;td&gt;Like 302 but guarantees method and body won't change when following redirect&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;308&lt;/td&gt;
&lt;td&gt;Permanent Redirect&lt;/td&gt;
&lt;td&gt;Like 301 but guarantees method and body won't change when following redirect&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  4xx Client Error Responses
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      The request contains bad syntax or cannot be fulfilled. These are the most common
      errors you'll encounter while debugging APIs.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;400&lt;/td&gt;
&lt;td&gt;Bad Request&lt;/td&gt;
&lt;td&gt;Malformed request syntax, invalid message framing, or deceptive request routing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;401&lt;/td&gt;
&lt;td&gt;Unauthorized&lt;/td&gt;
&lt;td&gt;Authentication is required or has failed. Include WWW-Authenticate header&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;402&lt;/td&gt;
&lt;td&gt;Payment Required&lt;/td&gt;
&lt;td&gt;Reserved for future use (digital payment systems). Rarely used in practice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;403&lt;/td&gt;
&lt;td&gt;Forbidden&lt;/td&gt;
&lt;td&gt;Server understood the request but refuses to authorize it. Different from 401&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;404&lt;/td&gt;
&lt;td&gt;Not Found&lt;/td&gt;
&lt;td&gt;Server cannot find the requested resource. The most famous HTTP error&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;405&lt;/td&gt;
&lt;td&gt;Method Not Allowed&lt;/td&gt;
&lt;td&gt;HTTP method not supported for this resource. Include Allow header&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;406&lt;/td&gt;
&lt;td&gt;Not Acceptable&lt;/td&gt;
&lt;td&gt;Resource cannot produce content matching Accept headers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;407&lt;/td&gt;
&lt;td&gt;Proxy Auth Required&lt;/td&gt;
&lt;td&gt;Client must first authenticate with the proxy (like 401 for proxies)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;408&lt;/td&gt;
&lt;td&gt;Request Timeout&lt;/td&gt;
&lt;td&gt;Server timed out waiting for the request. Client can re-send&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;409&lt;/td&gt;
&lt;td&gt;Conflict&lt;/td&gt;
&lt;td&gt;Request conflicts with current state of the resource (e.g., version conflicts)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;410&lt;/td&gt;
&lt;td&gt;Gone&lt;/td&gt;
&lt;td&gt;Resource is gone and will not be available again. Unlike 404, this is permanent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;411&lt;/td&gt;
&lt;td&gt;Length Required&lt;/td&gt;
&lt;td&gt;Content-Length header is required but was not provided&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;412&lt;/td&gt;
&lt;td&gt;Precondition Failed&lt;/td&gt;
&lt;td&gt;Conditional request headers (If-Match, If-None-Match) evaluated to false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;413&lt;/td&gt;
&lt;td&gt;Payload Too Large&lt;/td&gt;
&lt;td&gt;Request entity is larger than server is willing or able to process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;414&lt;/td&gt;
&lt;td&gt;URI Too Long&lt;/td&gt;
&lt;td&gt;URI requested is longer than server can interpret&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;415&lt;/td&gt;
&lt;td&gt;Unsupported Media Type&lt;/td&gt;
&lt;td&gt;Media format in Content-Type is not supported by the server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;416&lt;/td&gt;
&lt;td&gt;Range Not Satisfiable&lt;/td&gt;
&lt;td&gt;Range specified in Range header cannot be fulfilled&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;417&lt;/td&gt;
&lt;td&gt;Expectation Failed&lt;/td&gt;
&lt;td&gt;Server cannot meet the requirements of the Expect request header&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;418&lt;/td&gt;
&lt;td&gt;I'm a Teapot&lt;/td&gt;
&lt;td&gt;April Fools' joke (HTCPCP). Some servers use it for blocking bot traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;421&lt;/td&gt;
&lt;td&gt;Misdirected Request&lt;/td&gt;
&lt;td&gt;Request was directed at a server that cannot produce a response&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;422&lt;/td&gt;
&lt;td&gt;Unprocessable Entity&lt;/td&gt;
&lt;td&gt;Request body is syntactically correct but semantically invalid (validation errors)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;423&lt;/td&gt;
&lt;td&gt;Locked&lt;/td&gt;
&lt;td&gt;Resource is locked (WebDAV)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;424&lt;/td&gt;
&lt;td&gt;Failed Dependency&lt;/td&gt;
&lt;td&gt;Request failed because another request it depended on failed (WebDAV)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;425&lt;/td&gt;
&lt;td&gt;Too Early&lt;/td&gt;
&lt;td&gt;Server is unwilling to process a request that might be replayed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;426&lt;/td&gt;
&lt;td&gt;Upgrade Required&lt;/td&gt;
&lt;td&gt;Client should switch to a different protocol (e.g., HTTP/1.1 → HTTP/2)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;428&lt;/td&gt;
&lt;td&gt;Precondition Required&lt;/td&gt;
&lt;td&gt;Server requires the request to be conditional (prevent lost updates)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;429&lt;/td&gt;
&lt;td&gt;Too Many Requests&lt;/td&gt;
&lt;td&gt;Rate limit exceeded. Include Retry-After header. Very common in APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;431&lt;/td&gt;
&lt;td&gt;Header Fields Too Large&lt;/td&gt;
&lt;td&gt;Request header fields are too large (individual header or total size)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;451&lt;/td&gt;
&lt;td&gt;Unavailable For Legal Reasons&lt;/td&gt;
&lt;td&gt;Resource blocked due to legal demands (censorship, copyright takedowns)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  5xx Server Error Responses
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      The server failed to fulfill a valid request. These indicate problems on the server
      side — but sometimes the real issue is upstream.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Code&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;500&lt;/td&gt;
&lt;td&gt;Internal Server Error&lt;/td&gt;
&lt;td&gt;Generic server error when no specific message fits. Check server logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;501&lt;/td&gt;
&lt;td&gt;Not Implemented&lt;/td&gt;
&lt;td&gt;Server does not support the HTTP method. Unlike 405, this means server can't handle it at all&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;502&lt;/td&gt;
&lt;td&gt;Bad Gateway&lt;/td&gt;
&lt;td&gt;Server acting as gateway got an invalid response from upstream server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;503&lt;/td&gt;
&lt;td&gt;Service Unavailable&lt;/td&gt;
&lt;td&gt;Server temporarily overloaded or under maintenance. Include Retry-After header&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;504&lt;/td&gt;
&lt;td&gt;Gateway Timeout&lt;/td&gt;
&lt;td&gt;Server acting as gateway did not receive response from upstream in time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;505&lt;/td&gt;
&lt;td&gt;HTTP Version Not Supported&lt;/td&gt;
&lt;td&gt;Server does not support the HTTP protocol version used in the request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;506&lt;/td&gt;
&lt;td&gt;Variant Also Negotiates&lt;/td&gt;
&lt;td&gt;Server configuration error: circular reference in transparent content negotiation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;507&lt;/td&gt;
&lt;td&gt;Insufficient Storage&lt;/td&gt;
&lt;td&gt;Server cannot store the representation needed to complete the request (WebDAV)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;508&lt;/td&gt;
&lt;td&gt;Loop Detected&lt;/td&gt;
&lt;td&gt;Server detected an infinite loop processing the request (WebDAV)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;510&lt;/td&gt;
&lt;td&gt;Not Extended&lt;/td&gt;
&lt;td&gt;Further extensions to the request are required for the server to fulfill it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;511&lt;/td&gt;
&lt;td&gt;Network Auth Required&lt;/td&gt;
&lt;td&gt;Client needs to authenticate to gain network access (captive portals)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Quick Reference by Category
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Some status codes appear in unexpected places. Here's a breakdown of which codes
      are commonly seen in specific scenarios:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Common Codes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;REST API - GET&lt;/td&gt;
&lt;td&gt;200 (OK), 404 (Not Found), 401 (Unauthorized)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REST API - POST&lt;/td&gt;
&lt;td&gt;201 (Created), 400 (Bad Request), 422 (Unprocessable Entity), 409 (Conflict)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REST API - PUT/PATCH&lt;/td&gt;
&lt;td&gt;200 (OK), 204 (No Content), 409 (Conflict), 412 (Precondition Failed)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;REST API - DELETE&lt;/td&gt;
&lt;td&gt;204 (No Content), 404 (Not Found), 410 (Gone)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CDN / Proxy&lt;/td&gt;
&lt;td&gt;502 (Bad Gateway), 504 (Gateway Timeout), 301 (Moved Permanently)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rate Limiting&lt;/td&gt;
&lt;td&gt;429 (Too Many Requests), 503 (Service Unavailable)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth / Tokens&lt;/td&gt;
&lt;td&gt;401 (Unauthorized), 403 (Forbidden), 407 (Proxy Auth Required)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File Upload&lt;/td&gt;
&lt;td&gt;413 (Payload Too Large), 415 (Unsupported Media Type)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Redirects&lt;/td&gt;
&lt;td&gt;301 (Permanent), 302 (Temporary), 307 (Temporary, method-preserving), 308 (Permanent, method-preserving)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Common Mistakes &amp;amp; Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Don't Use 200 for Everything
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Many poorly designed APIs return `200 OK` for everything,
      including errors, and handle them in the response body. This breaks HTTP semantics
      and makes debugging harder. Use the correct status code for each scenario.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  2. 401 vs 403 — Know the Difference
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      `401 Unauthorized` means the client is not authenticated
      (no valid credentials). `403 Forbidden` means the client is
      authenticated but lacks permission. Use them correctly — a logged-in user hitting an
      admin endpoint should get 403, not 401.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  3. Always Return Proper Error Bodies
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      When returning 4xx or 5xx, include a structured error response body:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"error"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"VALIDATION_ERROR"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"Email is required"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;"details"&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="s2"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"issue"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"must not be empty"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Use Retry-After With 429 and 503
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      When rate-limiting (`429`) or serving maintenance pages
      (`503`), include the `Retry-After` header
      so clients know when to retry. This prevents thundering herd problems.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  5. 301 Redirects Are Cached by Browsers
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      A `301 Moved Permanently` redirect is aggressively cached
      by browsers. If you accidentally serve a 301 to the wrong URL, clients will cache it
      and you'll have trouble fixing it. Use `302` or
      `307` for temporary redirects.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;**** 🎯 Quick Summary&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;1xx — Informational: continue, switching protocols&lt;br&gt;
 2xx — Success: everything worked as expected&lt;br&gt;
 3xx — Redirection: resource moved, use different URL&lt;br&gt;
 4xx — Client Error: bad request, auth failure, not found (debug here first)&lt;br&gt;
 5xx — Server Error: server crashed, gateway timeout, overloaded&lt;br&gt;
 Use our &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;JSON Formatter&lt;/a&gt; to read API error responses&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is the difference between 401 Unauthorized and 403 Forbidden?
&lt;/h3&gt;

&lt;p&gt;401 Unauthorized means the client is&lt;br&gt;
                not authenticated — no valid credentials&lt;br&gt;
                were provided, or the token is missing or expired.&lt;br&gt;
                403 Forbidden means the client&lt;br&gt;
                is authenticated but does not have&lt;br&gt;
                permission to access the resource. A logged-in user hitting an admin endpoint&lt;br&gt;
                should get 403; an anonymous request should get 401. Also note that the spec&lt;br&gt;
                recommends 401 include a&lt;br&gt;
                WWW-Authenticate header describing the auth scheme.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between 301, 302, 307, and 308 redirects?
&lt;/h3&gt;

&lt;p&gt;301 and 308 are&lt;br&gt;
                permanent redirects; 302 and&lt;br&gt;
                307 are temporary. The key difference is method&lt;br&gt;
                handling: 301 and 302&lt;br&gt;
                may rewrite POST into GET&lt;br&gt;
                (most browsers do), while 307 and&lt;br&gt;
                308 always preserve the method and request body.&lt;br&gt;
                Use 308 for permanent redirects of form&lt;br&gt;
                submissions or API endpoints, and 307 for&lt;br&gt;
                temporary ones where the method must survive.&lt;/p&gt;

&lt;h3&gt;
  
  
  When should I return 429 Too Many Requests?
&lt;/h3&gt;

&lt;p&gt;Return 429 when a client exceeds your rate limit&lt;br&gt;
                — for example, more than 100 requests per minute. Always include a&lt;br&gt;
                Retry-After header (in seconds or an HTTP date)&lt;br&gt;
                so clients know when to try again, and consider adding&lt;br&gt;
                RateLimit-Limit,&lt;br&gt;
                RateLimit-Remaining, and&lt;br&gt;
                RateLimit-Reset headers for transparency. Use&lt;br&gt;
                503 instead when the whole service is overloaded&lt;br&gt;
                or down for maintenance, since that signals a server-side condition rather than a&lt;br&gt;
                client quota.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I return 404 or 403 for resources that exist but are not authorized?
&lt;/h3&gt;

&lt;p&gt;For security-sensitive resources, returning 404&lt;br&gt;
                is usually the better choice. A 403 tells an&lt;br&gt;
                attacker that the resource exists, letting them enumerate your API. Returning&lt;br&gt;
                404 for both "not found" and "forbidden" hides&lt;br&gt;
                the resource's existence. Reserve 403 for cases&lt;br&gt;
                where revealing existence is fine, such as a public site telling a logged-in user&lt;br&gt;
                they lack admin rights.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between 500, 502, 503, and 504?
&lt;/h3&gt;

&lt;p&gt;500 Internal Server Error is a generic failure&lt;br&gt;
                inside your application — an unhandled exception or misconfiguration.&lt;br&gt;
                502 Bad Gateway means an upstream server (like a&lt;br&gt;
                reverse proxy's backend) returned an invalid response.&lt;br&gt;
                503 Service Unavailable means the server is&lt;br&gt;
                overloaded or in maintenance — pair it with&lt;br&gt;
                Retry-After.&lt;br&gt;
                504 Gateway Timeout means an upstream server&lt;br&gt;
                didn't respond in time. All four are server-side: check your application logs,&lt;br&gt;
                upstream health, and load balancer configuration in that order.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        **Related Tools:**
        [JSON Formatter](https://devtoolshub.cloud/tools/json-formatter)

        [Base64 Encoder/Decoder](https://devtoolshub.cloud/tools/base64)

        [JWT Decoder](https://devtoolshub.cloud/tools/jwt-decoder)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>HTML Entities Reference: Every Escape Code You Need</title>
      <dc:creator>kingfujing</dc:creator>
      <pubDate>Thu, 12 Nov 2026 02:01:42 +0000</pubDate>
      <link>https://dev.to/kingfujing/html-entities-reference-every-escape-code-you-need-3obj</link>
      <guid>https://dev.to/kingfujing/html-entities-reference-every-escape-code-you-need-3obj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://devtoolshub.cloud/blog/html-entities-reference" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — free, privacy-first online tools for developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;HTML entities (also called character entities or escape codes) let you display&lt;br&gt;
          reserved characters, special symbols, and invisible characters in HTML documents.&lt;br&gt;
          Whether you need to show a literal &lt;code&gt;&amp;lt;&lt;/code&gt; without&lt;br&gt;
          triggering a tag, display a copyright symbol, or include an arrow in your UI,&lt;br&gt;
          this reference has the code.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Each table below lists the entity name, numeric code (decimal and hex), and the
      rendered character. Bookmark this page for quick lookup during frontend development.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;💡 How to Use&lt;/strong&gt; Use entity names like &amp;amp; or numeric&lt;br&gt;
 codes like &amp;amp; or&lt;br&gt;
 &amp;amp; directly in your HTML. Most modern&lt;br&gt;
 editors suggest entity names as you type.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Common Symbols
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      These are the most frequently used HTML entities. Every developer should know
      `&amp;amp;amp;`, `&amp;lt;`,
      `&amp;gt;`, and ` `
      by heart.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Character&lt;/th&gt;
&lt;th&gt;Entity Name&lt;/th&gt;
&lt;th&gt;Decimal Code&lt;/th&gt;
&lt;th&gt;Hex Code&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&amp;amp;&lt;/td&gt;
&lt;td&gt;&amp;amp;&lt;/td&gt;
&lt;td&gt;&amp;amp;&lt;/td&gt;
&lt;td&gt;&amp;amp;&lt;/td&gt;
&lt;td&gt;Ampersand (must escape in HTML)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;lt;&lt;/td&gt;
&lt;td&gt;&amp;lt;&lt;/td&gt;
&lt;td&gt;&amp;lt;&lt;/td&gt;
&lt;td&gt;&amp;lt;&lt;/td&gt;
&lt;td&gt;Less than (opens HTML tags)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&amp;gt;&lt;/td&gt;
&lt;td&gt;&amp;gt;&lt;/td&gt;
&lt;td&gt;&amp;gt;&lt;/td&gt;
&lt;td&gt;&amp;gt;&lt;/td&gt;
&lt;td&gt;Greater than (closes HTML tags)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"&lt;/td&gt;
&lt;td&gt;"&lt;/td&gt;
&lt;td&gt;"&lt;/td&gt;
&lt;td&gt;"&lt;/td&gt;
&lt;td&gt;Double quote (attribute delimiters)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;'&lt;/td&gt;
&lt;td&gt;'&lt;/td&gt;
&lt;td&gt;'&lt;/td&gt;
&lt;td&gt;'&lt;/td&gt;
&lt;td&gt;Apostrophe / single quote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;Non-breaking space (prevents line break)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;©&lt;/td&gt;
&lt;td&gt;©&lt;/td&gt;
&lt;td&gt;©&lt;/td&gt;
&lt;td&gt;©&lt;/td&gt;
&lt;td&gt;Copyright symbol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;®&lt;/td&gt;
&lt;td&gt;®&lt;/td&gt;
&lt;td&gt;®&lt;/td&gt;
&lt;td&gt;®&lt;/td&gt;
&lt;td&gt;Registered trademark&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;™&lt;/td&gt;
&lt;td&gt;™&lt;/td&gt;
&lt;td&gt;™&lt;/td&gt;
&lt;td&gt;™&lt;/td&gt;
&lt;td&gt;Trademark symbol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;§&lt;/td&gt;
&lt;td&gt;§&lt;/td&gt;
&lt;td&gt;§&lt;/td&gt;
&lt;td&gt;§&lt;/td&gt;
&lt;td&gt;Section symbol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¶&lt;/td&gt;
&lt;td&gt;¶&lt;/td&gt;
&lt;td&gt;¶&lt;/td&gt;
&lt;td&gt;¶&lt;/td&gt;
&lt;td&gt;Pilcrow / paragraph mark&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;°&lt;/td&gt;
&lt;td&gt;°&lt;/td&gt;
&lt;td&gt;°&lt;/td&gt;
&lt;td&gt;°&lt;/td&gt;
&lt;td&gt;Degree symbol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;†&lt;/td&gt;
&lt;td&gt;†&lt;/td&gt;
&lt;td&gt;†&lt;/td&gt;
&lt;td&gt;†&lt;/td&gt;
&lt;td&gt;Dagger (footnotes)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;‡&lt;/td&gt;
&lt;td&gt;‡&lt;/td&gt;
&lt;td&gt;‡&lt;/td&gt;
&lt;td&gt;‡&lt;/td&gt;
&lt;td&gt;Double dagger&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;•&lt;/td&gt;
&lt;td&gt;•&lt;/td&gt;
&lt;td&gt;•&lt;/td&gt;
&lt;td&gt;•&lt;/td&gt;
&lt;td&gt;Bullet point&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;td&gt;…&lt;/td&gt;
&lt;td&gt;Horizontal ellipsis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;‰&lt;/td&gt;
&lt;td&gt;‰&lt;/td&gt;
&lt;td&gt;‰&lt;/td&gt;
&lt;td&gt;‰&lt;/td&gt;
&lt;td&gt;Per mille (per thousand)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;℠&lt;/td&gt;
&lt;td&gt;&amp;amp;scaps;&lt;/td&gt;
&lt;td&gt;℠&lt;/td&gt;
&lt;td&gt;℠&lt;/td&gt;
&lt;td&gt;Service mark&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Currency Symbols
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Display currency signs from around the world. Note that some symbols (like the
      Bitcoin sign) may not render in older browsers without a numeric code.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Character&lt;/th&gt;
&lt;th&gt;Entity Name&lt;/th&gt;
&lt;th&gt;Decimal Code&lt;/th&gt;
&lt;th&gt;Hex Code&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$&lt;/td&gt;
&lt;td&gt;(none needed)&lt;/td&gt;
&lt;td&gt;$&lt;/td&gt;
&lt;td&gt;$&lt;/td&gt;
&lt;td&gt;Dollar (not reserved, no entity needed)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¢&lt;/td&gt;
&lt;td&gt;¢&lt;/td&gt;
&lt;td&gt;¢&lt;/td&gt;
&lt;td&gt;¢&lt;/td&gt;
&lt;td&gt;Cent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;£&lt;/td&gt;
&lt;td&gt;£&lt;/td&gt;
&lt;td&gt;£&lt;/td&gt;
&lt;td&gt;£&lt;/td&gt;
&lt;td&gt;Pound sterling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¤&lt;/td&gt;
&lt;td&gt;¤&lt;/td&gt;
&lt;td&gt;¤&lt;/td&gt;
&lt;td&gt;¤&lt;/td&gt;
&lt;td&gt;Generic currency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¥&lt;/td&gt;
&lt;td&gt;¥&lt;/td&gt;
&lt;td&gt;¥&lt;/td&gt;
&lt;td&gt;¥&lt;/td&gt;
&lt;td&gt;Yen / Yuan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;€&lt;/td&gt;
&lt;td&gt;€&lt;/td&gt;
&lt;td&gt;€&lt;/td&gt;
&lt;td&gt;€&lt;/td&gt;
&lt;td&gt;Euro&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;₤&lt;/td&gt;
&lt;td&gt;&amp;amp;lira;&lt;/td&gt;
&lt;td&gt;₤&lt;/td&gt;
&lt;td&gt;₤&lt;/td&gt;
&lt;td&gt;Lira sign&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;₱&lt;/td&gt;
&lt;td&gt;(none)&lt;/td&gt;
&lt;td&gt;₱&lt;/td&gt;
&lt;td&gt;₱&lt;/td&gt;
&lt;td&gt;Philippine peso&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;₹&lt;/td&gt;
&lt;td&gt;(none)&lt;/td&gt;
&lt;td&gt;₹&lt;/td&gt;
&lt;td&gt;₹&lt;/td&gt;
&lt;td&gt;Indian rupee&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;₩&lt;/td&gt;
&lt;td&gt;(none)&lt;/td&gt;
&lt;td&gt;₩&lt;/td&gt;
&lt;td&gt;₩&lt;/td&gt;
&lt;td&gt;South Korean won&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;₪&lt;/td&gt;
&lt;td&gt;(none)&lt;/td&gt;
&lt;td&gt;₪&lt;/td&gt;
&lt;td&gt;₪&lt;/td&gt;
&lt;td&gt;Israeli shekel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;₫&lt;/td&gt;
&lt;td&gt;(none)&lt;/td&gt;
&lt;td&gt;₫&lt;/td&gt;
&lt;td&gt;₫&lt;/td&gt;
&lt;td&gt;Vietnamese dong&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;₮&lt;/td&gt;
&lt;td&gt;(none)&lt;/td&gt;
&lt;td&gt;₮&lt;/td&gt;
&lt;td&gt;₮&lt;/td&gt;
&lt;td&gt;Mongolian tugrik&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;₽&lt;/td&gt;
&lt;td&gt;(none)&lt;/td&gt;
&lt;td&gt;₽&lt;/td&gt;
&lt;td&gt;₽&lt;/td&gt;
&lt;td&gt;Russian ruble&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;₿&lt;/td&gt;
&lt;td&gt;(none)&lt;/td&gt;
&lt;td&gt;₿&lt;/td&gt;
&lt;td&gt;₿&lt;/td&gt;
&lt;td&gt;Bitcoin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;₣&lt;/td&gt;
&lt;td&gt;(none)&lt;/td&gt;
&lt;td&gt;₣&lt;/td&gt;
&lt;td&gt;₣&lt;/td&gt;
&lt;td&gt;French franc&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Arrows
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Arrow symbols for navigation, direction indicators, and UI elements. Both simple
      and double-lined variants are available.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Character&lt;/th&gt;
&lt;th&gt;Entity Name&lt;/th&gt;
&lt;th&gt;Decimal Code&lt;/th&gt;
&lt;th&gt;Hex Code&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;←&lt;/td&gt;
&lt;td&gt;←&lt;/td&gt;
&lt;td&gt;←&lt;/td&gt;
&lt;td&gt;←&lt;/td&gt;
&lt;td&gt;Left arrow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;↑&lt;/td&gt;
&lt;td&gt;↑&lt;/td&gt;
&lt;td&gt;↑&lt;/td&gt;
&lt;td&gt;↑&lt;/td&gt;
&lt;td&gt;Up arrow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;→&lt;/td&gt;
&lt;td&gt;→&lt;/td&gt;
&lt;td&gt;→&lt;/td&gt;
&lt;td&gt;→&lt;/td&gt;
&lt;td&gt;Right arrow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;↓&lt;/td&gt;
&lt;td&gt;↓&lt;/td&gt;
&lt;td&gt;↓&lt;/td&gt;
&lt;td&gt;↓&lt;/td&gt;
&lt;td&gt;Down arrow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;↔&lt;/td&gt;
&lt;td&gt;↔&lt;/td&gt;
&lt;td&gt;↔&lt;/td&gt;
&lt;td&gt;↔&lt;/td&gt;
&lt;td&gt;Left-right arrow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;↕&lt;/td&gt;
&lt;td&gt;↕&lt;/td&gt;
&lt;td&gt;↕&lt;/td&gt;
&lt;td&gt;↕&lt;/td&gt;
&lt;td&gt;Up-down arrow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;↖&lt;/td&gt;
&lt;td&gt;↖&lt;/td&gt;
&lt;td&gt;↖&lt;/td&gt;
&lt;td&gt;↖&lt;/td&gt;
&lt;td&gt;North-west arrow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;↗&lt;/td&gt;
&lt;td&gt;↗&lt;/td&gt;
&lt;td&gt;↗&lt;/td&gt;
&lt;td&gt;↗&lt;/td&gt;
&lt;td&gt;North-east arrow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;↘&lt;/td&gt;
&lt;td&gt;↘&lt;/td&gt;
&lt;td&gt;↘&lt;/td&gt;
&lt;td&gt;↘&lt;/td&gt;
&lt;td&gt;South-east arrow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;↙&lt;/td&gt;
&lt;td&gt;↙&lt;/td&gt;
&lt;td&gt;↙&lt;/td&gt;
&lt;td&gt;↙&lt;/td&gt;
&lt;td&gt;South-west arrow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⇐&lt;/td&gt;
&lt;td&gt;⇐&lt;/td&gt;
&lt;td&gt;⇐&lt;/td&gt;
&lt;td&gt;⇐&lt;/td&gt;
&lt;td&gt;Left double arrow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⇒&lt;/td&gt;
&lt;td&gt;⇒&lt;/td&gt;
&lt;td&gt;⇒&lt;/td&gt;
&lt;td&gt;⇒&lt;/td&gt;
&lt;td&gt;Right double arrow (implies)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⇔&lt;/td&gt;
&lt;td&gt;⇔&lt;/td&gt;
&lt;td&gt;⇔&lt;/td&gt;
&lt;td&gt;⇔&lt;/td&gt;
&lt;td&gt;Left-right double arrow (iff)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;►&lt;/td&gt;
&lt;td&gt;▸&lt;/td&gt;
&lt;td&gt;▸&lt;/td&gt;
&lt;td&gt;▶&lt;/td&gt;
&lt;td&gt;Right-pointing triangle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;◄&lt;/td&gt;
&lt;td&gt;◂&lt;/td&gt;
&lt;td&gt;◀&lt;/td&gt;
&lt;td&gt;◀&lt;/td&gt;
&lt;td&gt;Left-pointing triangle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;▲&lt;/td&gt;
&lt;td&gt;▴&lt;/td&gt;
&lt;td&gt;▴&lt;/td&gt;
&lt;td&gt;▴&lt;/td&gt;
&lt;td&gt;Up-pointing triangle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;▼&lt;/td&gt;
&lt;td&gt;▾&lt;/td&gt;
&lt;td&gt;▾&lt;/td&gt;
&lt;td&gt;▾&lt;/td&gt;
&lt;td&gt;Down-pointing triangle&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Mathematical Operators &amp;amp; Symbols
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Common math symbols for equations, comparisons, fractions, and logic. Use numeric
      codes for symbols without named entities.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Character&lt;/th&gt;
&lt;th&gt;Entity Name&lt;/th&gt;
&lt;th&gt;Decimal Code&lt;/th&gt;
&lt;th&gt;Hex Code&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;×&lt;/td&gt;
&lt;td&gt;×&lt;/td&gt;
&lt;td&gt;×&lt;/td&gt;
&lt;td&gt;×&lt;/td&gt;
&lt;td&gt;Multiplication sign&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;÷&lt;/td&gt;
&lt;td&gt;÷&lt;/td&gt;
&lt;td&gt;÷&lt;/td&gt;
&lt;td&gt;÷&lt;/td&gt;
&lt;td&gt;Division sign&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;±&lt;/td&gt;
&lt;td&gt;±&lt;/td&gt;
&lt;td&gt;±&lt;/td&gt;
&lt;td&gt;±&lt;/td&gt;
&lt;td&gt;Plus-minus&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;−&lt;/td&gt;
&lt;td&gt;−&lt;/td&gt;
&lt;td&gt;−&lt;/td&gt;
&lt;td&gt;−&lt;/td&gt;
&lt;td&gt;Minus sign (not hyphen)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;∑&lt;/td&gt;
&lt;td&gt;∑&lt;/td&gt;
&lt;td&gt;∑&lt;/td&gt;
&lt;td&gt;∑&lt;/td&gt;
&lt;td&gt;N-ary summation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;∏&lt;/td&gt;
&lt;td&gt;∏&lt;/td&gt;
&lt;td&gt;∏&lt;/td&gt;
&lt;td&gt;∏&lt;/td&gt;
&lt;td&gt;N-ary product&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;∫&lt;/td&gt;
&lt;td&gt;∫&lt;/td&gt;
&lt;td&gt;∫&lt;/td&gt;
&lt;td&gt;∫&lt;/td&gt;
&lt;td&gt;Integral&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;√&lt;/td&gt;
&lt;td&gt;√&lt;/td&gt;
&lt;td&gt;√&lt;/td&gt;
&lt;td&gt;√&lt;/td&gt;
&lt;td&gt;Square root&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;∞&lt;/td&gt;
&lt;td&gt;∞&lt;/td&gt;
&lt;td&gt;∞&lt;/td&gt;
&lt;td&gt;∞&lt;/td&gt;
&lt;td&gt;Infinity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;∠&lt;/td&gt;
&lt;td&gt;∠&lt;/td&gt;
&lt;td&gt;∠&lt;/td&gt;
&lt;td&gt;∠&lt;/td&gt;
&lt;td&gt;Angle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⊥&lt;/td&gt;
&lt;td&gt;⊥&lt;/td&gt;
&lt;td&gt;⊥&lt;/td&gt;
&lt;td&gt;⊥&lt;/td&gt;
&lt;td&gt;Perpendicular / up tack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;∴&lt;/td&gt;
&lt;td&gt;∴&lt;/td&gt;
&lt;td&gt;∴&lt;/td&gt;
&lt;td&gt;∴&lt;/td&gt;
&lt;td&gt;Therefore&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;∵&lt;/td&gt;
&lt;td&gt;∵&lt;/td&gt;
&lt;td&gt;∵&lt;/td&gt;
&lt;td&gt;∵&lt;/td&gt;
&lt;td&gt;Because&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;∼&lt;/td&gt;
&lt;td&gt;∼&lt;/td&gt;
&lt;td&gt;∼&lt;/td&gt;
&lt;td&gt;∼&lt;/td&gt;
&lt;td&gt;Tilde operator (similar to)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;≅&lt;/td&gt;
&lt;td&gt;≅&lt;/td&gt;
&lt;td&gt;≅&lt;/td&gt;
&lt;td&gt;≅&lt;/td&gt;
&lt;td&gt;Approximately equal to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;≈&lt;/td&gt;
&lt;td&gt;≈&lt;/td&gt;
&lt;td&gt;≈&lt;/td&gt;
&lt;td&gt;≈&lt;/td&gt;
&lt;td&gt;Almost equal to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;≠&lt;/td&gt;
&lt;td&gt;≠&lt;/td&gt;
&lt;td&gt;≠&lt;/td&gt;
&lt;td&gt;≠&lt;/td&gt;
&lt;td&gt;Not equal to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;≡&lt;/td&gt;
&lt;td&gt;≡&lt;/td&gt;
&lt;td&gt;≡&lt;/td&gt;
&lt;td&gt;≡&lt;/td&gt;
&lt;td&gt;Identical to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;≤&lt;/td&gt;
&lt;td&gt;≤&lt;/td&gt;
&lt;td&gt;≤&lt;/td&gt;
&lt;td&gt;≤&lt;/td&gt;
&lt;td&gt;Less-than or equal to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;≥&lt;/td&gt;
&lt;td&gt;≥&lt;/td&gt;
&lt;td&gt;≥&lt;/td&gt;
&lt;td&gt;≥&lt;/td&gt;
&lt;td&gt;Greater-than or equal to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;½&lt;/td&gt;
&lt;td&gt;½&lt;/td&gt;
&lt;td&gt;½&lt;/td&gt;
&lt;td&gt;½&lt;/td&gt;
&lt;td&gt;Fraction one-half&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¼&lt;/td&gt;
&lt;td&gt;¼&lt;/td&gt;
&lt;td&gt;¼&lt;/td&gt;
&lt;td&gt;¼&lt;/td&gt;
&lt;td&gt;Fraction one-quarter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¾&lt;/td&gt;
&lt;td&gt;¾&lt;/td&gt;
&lt;td&gt;¾&lt;/td&gt;
&lt;td&gt;¾&lt;/td&gt;
&lt;td&gt;Fraction three-quarters&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;π&lt;/td&gt;
&lt;td&gt;π&lt;/td&gt;
&lt;td&gt;π&lt;/td&gt;
&lt;td&gt;π&lt;/td&gt;
&lt;td&gt;Greek pi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;μ&lt;/td&gt;
&lt;td&gt;μ&lt;/td&gt;
&lt;td&gt;μ&lt;/td&gt;
&lt;td&gt;μ&lt;/td&gt;
&lt;td&gt;Mu (micro symbol)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Punctuation &amp;amp; Special Characters
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Dashes, quotes, spaces, and other typographic characters for polished text.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Character&lt;/th&gt;
&lt;th&gt;Entity Name&lt;/th&gt;
&lt;th&gt;Decimal Code&lt;/th&gt;
&lt;th&gt;Hex Code&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;–&lt;/td&gt;
&lt;td&gt;–&lt;/td&gt;
&lt;td&gt;–&lt;/td&gt;
&lt;td&gt;–&lt;/td&gt;
&lt;td&gt;En dash (number ranges)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;Em dash (parenthetical)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;‘&lt;/td&gt;
&lt;td&gt;‘&lt;/td&gt;
&lt;td&gt;‘&lt;/td&gt;
&lt;td&gt;‘&lt;/td&gt;
&lt;td&gt;Left single quotation mark&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;’&lt;/td&gt;
&lt;td&gt;’&lt;/td&gt;
&lt;td&gt;’&lt;/td&gt;
&lt;td&gt;’&lt;/td&gt;
&lt;td&gt;Right single quotation mark&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;“&lt;/td&gt;
&lt;td&gt;“&lt;/td&gt;
&lt;td&gt;“&lt;/td&gt;
&lt;td&gt;“&lt;/td&gt;
&lt;td&gt;Left double quotation mark&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;”&lt;/td&gt;
&lt;td&gt;”&lt;/td&gt;
&lt;td&gt;”&lt;/td&gt;
&lt;td&gt;”&lt;/td&gt;
&lt;td&gt;Right double quotation mark&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;«&lt;/td&gt;
&lt;td&gt;«&lt;/td&gt;
&lt;td&gt;«&lt;/td&gt;
&lt;td&gt;«&lt;/td&gt;
&lt;td&gt;Left-pointing double angle (guillemet)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;»&lt;/td&gt;
&lt;td&gt;»&lt;/td&gt;
&lt;td&gt;»&lt;/td&gt;
&lt;td&gt;»&lt;/td&gt;
&lt;td&gt;Right-pointing double angle (guillemet)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;‹&lt;/td&gt;
&lt;td&gt;‹&lt;/td&gt;
&lt;td&gt;‹&lt;/td&gt;
&lt;td&gt;‹&lt;/td&gt;
&lt;td&gt;Single left-pointing angle quote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;›&lt;/td&gt;
&lt;td&gt;›&lt;/td&gt;
&lt;td&gt;›&lt;/td&gt;
&lt;td&gt;›&lt;/td&gt;
&lt;td&gt;Single right-pointing angle quote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¡&lt;/td&gt;
&lt;td&gt;¡&lt;/td&gt;
&lt;td&gt;¡&lt;/td&gt;
&lt;td&gt;¡&lt;/td&gt;
&lt;td&gt;Inverted exclamation mark&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¿&lt;/td&gt;
&lt;td&gt;¿&lt;/td&gt;
&lt;td&gt;¿&lt;/td&gt;
&lt;td&gt;¿&lt;/td&gt;
&lt;td&gt;Inverted question mark&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¦&lt;/td&gt;
&lt;td&gt;¦&lt;/td&gt;
&lt;td&gt;¦&lt;/td&gt;
&lt;td&gt;¦&lt;/td&gt;
&lt;td&gt;Broken vertical bar&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;¬&lt;/td&gt;
&lt;td&gt;¬&lt;/td&gt;
&lt;td&gt;¬&lt;/td&gt;
&lt;td&gt;¬&lt;/td&gt;
&lt;td&gt;Not sign&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;­&lt;/td&gt;
&lt;td&gt;­&lt;/td&gt;
&lt;td&gt;­&lt;/td&gt;
&lt;td&gt;­&lt;/td&gt;
&lt;td&gt;Soft hyphen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt; &lt;/td&gt;
&lt;td&gt; &lt;/td&gt;
&lt;td&gt; &lt;/td&gt;
&lt;td&gt;En space (half an em)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt; &lt;/td&gt;
&lt;td&gt; &lt;/td&gt;
&lt;td&gt; &lt;/td&gt;
&lt;td&gt;Em space (width of capital M)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt; &lt;/td&gt;
&lt;td&gt; &lt;/td&gt;
&lt;td&gt; &lt;/td&gt;
&lt;td&gt;Thin space&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Greek Letters (Common)
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Frequently used Greek letters in math, science, and engineering contexts.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Character&lt;/th&gt;
&lt;th&gt;Entity Name&lt;/th&gt;
&lt;th&gt;Decimal Code&lt;/th&gt;
&lt;th&gt;Hex Code&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;α&lt;/td&gt;
&lt;td&gt;α&lt;/td&gt;
&lt;td&gt;α&lt;/td&gt;
&lt;td&gt;α&lt;/td&gt;
&lt;td&gt;Alpha&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;β&lt;/td&gt;
&lt;td&gt;β&lt;/td&gt;
&lt;td&gt;β&lt;/td&gt;
&lt;td&gt;β&lt;/td&gt;
&lt;td&gt;Beta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;γ&lt;/td&gt;
&lt;td&gt;γ&lt;/td&gt;
&lt;td&gt;γ&lt;/td&gt;
&lt;td&gt;γ&lt;/td&gt;
&lt;td&gt;Gamma&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;δ&lt;/td&gt;
&lt;td&gt;δ&lt;/td&gt;
&lt;td&gt;δ&lt;/td&gt;
&lt;td&gt;δ&lt;/td&gt;
&lt;td&gt;Delta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ε&lt;/td&gt;
&lt;td&gt;ε&lt;/td&gt;
&lt;td&gt;ε&lt;/td&gt;
&lt;td&gt;ε&lt;/td&gt;
&lt;td&gt;Epsilon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;θ&lt;/td&gt;
&lt;td&gt;θ&lt;/td&gt;
&lt;td&gt;θ&lt;/td&gt;
&lt;td&gt;θ&lt;/td&gt;
&lt;td&gt;Theta&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;λ&lt;/td&gt;
&lt;td&gt;λ&lt;/td&gt;
&lt;td&gt;λ&lt;/td&gt;
&lt;td&gt;λ&lt;/td&gt;
&lt;td&gt;Lambda&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;σ&lt;/td&gt;
&lt;td&gt;σ&lt;/td&gt;
&lt;td&gt;σ&lt;/td&gt;
&lt;td&gt;σ&lt;/td&gt;
&lt;td&gt;Sigma&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;φ&lt;/td&gt;
&lt;td&gt;φ&lt;/td&gt;
&lt;td&gt;φ&lt;/td&gt;
&lt;td&gt;φ&lt;/td&gt;
&lt;td&gt;Phi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ω&lt;/td&gt;
&lt;td&gt;ω&lt;/td&gt;
&lt;td&gt;ω&lt;/td&gt;
&lt;td&gt;ω&lt;/td&gt;
&lt;td&gt;Omega&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;**** 🎯 Quick Reference: Most Common Entities&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&amp;amp;&lt;br&gt;
 &amp;amp;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;          &amp;lt;

          `&amp;lt;`


          &amp;gt;

          `&amp;gt;`


          "

          `&amp;amp;quot;`




          ` `


          ©

          `&amp;amp;copy;`


          ®

          `&amp;amp;reg;`


          €

          `&amp;amp;euro;`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Common Mistakes &amp;amp; How to Avoid Them
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Entities look simple, but a few recurring mistakes cause broken pages, escaped-looking
      text, and subtle layout bugs. Here are the five most common ones.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  1. Forgetting to escape the ampersand itself
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      The `&amp;amp;amp;` entity is special: because
      `&amp;amp;` starts every entity, a literal ampersand in your
      text (like `AT&amp;amp;T` or
      `R&amp;amp;D`) must be written as
      `&amp;amp;amp;`. Otherwise the browser may try to parse
      `&amp;amp;T` or `&amp;amp;D` as an
      entity and render unexpected characters.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- BUG: ambiguous, may render wrong --&amp;gt;&lt;/span&gt;
Acme &amp;amp; Sons

&lt;span class="c"&gt;&amp;lt;!-- FIX: escape the ampersand --&amp;gt;&lt;/span&gt;
Acme &amp;amp; Sons

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Dropping the trailing semicolon
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Writing `&amp;amp;copy` without the semicolon works in HTML5 in
      some contexts but is invalid in XHTML and risky inside attribute values. Always include the
      semicolon: `&amp;amp;copy;`. The same applies to numeric
      references — `&amp;amp;#169;` is correct,
      `&amp;amp;#169` is not.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  3. Double-escaping entities
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      If your page shows `&amp;amp;amp;lt;` as literal text instead of
      a `&amp;lt;` character, the content was escaped twice — once by
      your template engine or framework (React, Vue, Handlebars escape by default), then again by
      you. Pick one layer: let the framework escape user input, and never feed already-escaped
      strings into `dangerouslySetInnerHTML` or
      `innerHTML`.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c1"&gt;// BUG: React already escapes, so this renders "&amp;lt;" as text&lt;/span&gt;

&lt;span class="c1"&gt;// FIX: write the raw character — React escapes it safely&lt;/span&gt;

&lt;span class="c1"&gt;// BUG: double-escaping user input for innerHTML&lt;/span&gt;
&lt;span class="nt"&gt;el&lt;/span&gt;&lt;span class="nc"&gt;.innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;escapeHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;userInput&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nc"&gt;.replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;/&amp;amp;/&lt;/span&gt;&lt;span class="nt"&gt;g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;amp;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Using   for layout spacing
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Stacking ` ` entities to indent or align text works
      visually but breaks on narrow screens and with different font metrics. A non-breaking space
      also stops text from wrapping, which can push layout unexpectedly. Use CSS
      `margin`, `padding`, or
      `gap` for spacing instead — reserve
      ` ` for keeping two words on the same line (for
      example, "10 kg" or "Chapter 5").
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  5. Confusing decimal and hex numeric references
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      `&amp;amp;#38;` (decimal) and
      `&amp;amp;#x26;` (hex) both render
      `&amp;amp;`, but they are not interchangeable digits. Writing
      `&amp;amp;#x38;` renders the character `8`,
      not `&amp;amp;`. Check the prefix:
      `#x` means hexadecimal, plain
      `#` means decimal.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Why use HTML entities instead of typing the character directly?
&lt;/h3&gt;

&lt;p&gt;Three reasons: reserved characters like&lt;br&gt;
                &amp;lt;, &amp;gt;, and&lt;br&gt;
                &amp;amp; would be interpreted as markup;&lt;br&gt;
                encoding safety — an entity works even if the file encoding drops&lt;br&gt;
                the character (for example, a smart quote in a document declared as ASCII); and&lt;br&gt;
                reliability — invisible characters such as the non-breaking space&lt;br&gt;
                are hard to type and easy to mistake for a regular space.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is the difference between   and a regular space?
&lt;/h3&gt;

&lt;p&gt;A non-breaking space ( , U+00A0) prevents&lt;br&gt;
                the browser from wrapping a line at that point, so "10 kg" stays together. It also&lt;br&gt;
                does not collapse: HTML collapses runs of regular spaces into one, but multiple&lt;br&gt;
                  entities each keep their width, which is&lt;br&gt;
                why they are often misused for indentation. Use them for preventing breaks, not for&lt;br&gt;
                layout.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is the difference between &amp;amp;, &amp;amp;, and &amp;amp;?
&lt;/h3&gt;

&lt;p&gt;All three render the same &amp;amp; character.&lt;br&gt;
                &amp;amp; is the named entity — readable but only&lt;br&gt;
                available for characters that have a defined name. &amp;amp;&lt;br&gt;
                is the decimal numeric reference and &amp;amp; the&lt;br&gt;
                hex one; numeric references work for any Unicode code point, even ones without a&lt;br&gt;
                name. Use named entities for readability and numeric references for obscure symbols.&lt;/p&gt;
&lt;h3&gt;
  
  
  Do I need to escape quotes inside HTML attributes?
&lt;/h3&gt;

&lt;p&gt;Only the quote that delimits the attribute needs escaping: in&lt;br&gt;
                &lt;a title="Say "&gt; the&lt;br&gt;
                inner double quotes must be ". Inside text&lt;br&gt;
                content, quotes are harmless and do not need escaping. Escaping them everywhere is&lt;br&gt;
                never wrong, but it makes source harder to read — escape only where required, and&lt;br&gt;
                prefer single quotes as attribute delimiters when the value contains double quotes.&lt;/a&gt;&lt;/p&gt;
&lt;a title="Say "&gt;
&lt;/a&gt;&lt;h3&gt;
&lt;a title="Say "&gt;
  &lt;/a&gt;
  
  Why does my page show &amp;lt; as literal text instead of &amp;lt;?
&lt;/h3&gt;

&lt;p&gt;The text was escaped twice. If you write &amp;lt;&lt;br&gt;
                in your source, the browser parses &amp;amp; into&lt;br&gt;
                &amp;amp; and shows the literal text&lt;br&gt;
                &amp;lt;. This usually happens when a template&lt;br&gt;
                engine or framework that already escapes output receives pre-escaped input, or when&lt;br&gt;
                user input is escaped more than once. Escape at exactly one layer.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        **Related Tools:**
        [Base64 Encoder/Decoder](https://devtoolshub.cloud/tools/base64)

        [JSON Formatter](https://devtoolshub.cloud/tools/json-formatter)

        [Regex Tester](https://devtoolshub.cloud/tools/regex-tester)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>webdev</category>
      <category>html</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Cron Expression Guide: Complete Reference with Examples</title>
      <dc:creator>kingfujing</dc:creator>
      <pubDate>Thu, 12 Nov 2026 02:00:36 +0000</pubDate>
      <link>https://dev.to/kingfujing/cron-expression-guide-complete-reference-with-examples-120p</link>
      <guid>https://dev.to/kingfujing/cron-expression-guide-complete-reference-with-examples-120p</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://devtoolshub.cloud/blog/cron-expression-guide" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — free, privacy-first online tools for developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cron is the time-based job scheduler built into Unix-like operating systems. It&lt;br&gt;
          lets you schedule commands or scripts to run at specific times — every minute, every&lt;br&gt;
          Tuesday at 3 AM, or the first day of every quarter. Despite its power, the syntax&lt;br&gt;
          can be cryptic for beginners and even experienced developers find themselves checking&lt;br&gt;
          references regularly.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      This guide covers everything you need to know about cron expressions: the five
      standard fields, special strings, real-world schedule examples, troubleshooting tips,
      and timezone considerations. Whether you're writing a crontab file or configuring
      a cloud scheduler, this reference has you covered.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚡ Quick Tip&lt;/strong&gt; Use our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/tools/timestamp" rel="noopener noreferrer"&gt;&lt;br&gt;
 Unix Timestamp Converter&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 to convert cron timestamps to human-readable dates during debugging, and our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;&lt;br&gt;
 JSON Formatter&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 to read cron job output logs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. Cron Syntax Fundamentals
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      A standard cron expression has five fields, separated by spaces:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Position&lt;/th&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Range&lt;/th&gt;
&lt;th&gt;Allowed Special Chars&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Minute&lt;/td&gt;
&lt;td&gt;0 - 59&lt;/td&gt;
&lt;td&gt;* , - /&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Hour&lt;/td&gt;
&lt;td&gt;0 - 23&lt;/td&gt;
&lt;td&gt;* , - /&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Day of Month&lt;/td&gt;
&lt;td&gt;1 - 31&lt;/td&gt;
&lt;td&gt;* , - / ? L W&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Month&lt;/td&gt;
&lt;td&gt;1 - 12 (or JAN - DEC)&lt;/td&gt;
&lt;td&gt;* , - /&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Day of Week&lt;/td&gt;
&lt;td&gt;0 - 7 (or SUN - SAT)&lt;/td&gt;
&lt;td&gt;* , - / ? L #&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      **Important note on Day of Week:** Both 0 and 7
      represent Sunday. Most systems use 0 for Sunday, 1 for Monday, through 6 for Saturday.
      Some systems (like Quartz) use 1 for Sunday and 2-7 for Monday-Saturday — always check
      your implementation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Special Characters
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Char&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;*&lt;/td&gt;
&lt;td&gt;Wildcard&lt;/td&gt;
&lt;td&gt;Every value in the field&lt;/td&gt;
&lt;td&gt;* * * * * = every minute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;,&lt;/td&gt;
&lt;td&gt;List&lt;/td&gt;
&lt;td&gt;Multiple values&lt;/td&gt;
&lt;td&gt;0,30 * * * * = at :00 and :30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Range&lt;/td&gt;
&lt;td&gt;All values in a range&lt;/td&gt;
&lt;td&gt;0 9-17 * * * = 9 AM to 5 PM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/&lt;/td&gt;
&lt;td&gt;Step&lt;/td&gt;
&lt;td&gt;Every N units&lt;/td&gt;
&lt;td&gt;*/15 * * * * = every 15 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;?&lt;/td&gt;
&lt;td&gt;No specific value&lt;/td&gt;
&lt;td&gt;Used in day-of-month/day-of-week (alternative to *)&lt;/td&gt;
&lt;td&gt;0 0 ? * MON = every Monday&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;L&lt;/td&gt;
&lt;td&gt;Last&lt;/td&gt;
&lt;td&gt;Last day of month or week&lt;/td&gt;
&lt;td&gt;0 0 L * * = last day of month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;W&lt;/td&gt;
&lt;td&gt;Weekday&lt;/td&gt;
&lt;td&gt;Nearest weekday to given day&lt;/td&gt;
&lt;td&gt;0 0 15W * * = nearest weekday to 15th&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;#&lt;/td&gt;
&lt;td&gt;Nth occurrence&lt;/td&gt;
&lt;td&gt;Nth weekday of the month&lt;/td&gt;
&lt;td&gt;0 0 ? * 2#1 = first Monday&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ ? vs * in Cron&lt;/strong&gt; In standard Unix cron, * is used everywhere.&lt;br&gt;
 The ? character is specific to Quartz-style cron&lt;br&gt;
 expressions (used by Java-based schedulers like Spring). In Quartz, only one of&lt;br&gt;
 day-of-month or day-of-week can be specified — the other must be&lt;br&gt;
 ? .&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  2. Special Strings
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Many cron implementations support shorthand strings for common schedules. These are
      especially useful in cloud schedulers (AWS EventBridge, Google Cloud Scheduler) and
      systemd timers.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;String&lt;/th&gt;
&lt;th&gt;Equivalent Expression&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;@yearly&lt;/td&gt;
&lt;td&gt;0 0 1 1 *&lt;/td&gt;
&lt;td&gt;Run once a year at midnight on January 1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@annually&lt;/td&gt;
&lt;td&gt;0 0 1 1 *&lt;/td&gt;
&lt;td&gt;Same as @yearly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@monthly&lt;/td&gt;
&lt;td&gt;0 0 1 * *&lt;/td&gt;
&lt;td&gt;Run once a month at midnight on the first day&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@weekly&lt;/td&gt;
&lt;td&gt;0 0 * * 0&lt;/td&gt;
&lt;td&gt;Run once a week at midnight on Sunday&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@daily&lt;/td&gt;
&lt;td&gt;0 0 * * *&lt;/td&gt;
&lt;td&gt;Run once a day at midnight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a class="mentioned-user" href="https://dev.to/midnight"&gt;@midnight&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;0 0 * * *&lt;/td&gt;
&lt;td&gt;Same as @daily&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;@hourly&lt;/td&gt;
&lt;td&gt;0 * * * *&lt;/td&gt;
&lt;td&gt;Run once an hour at minute 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a class="mentioned-user" href="https://dev.to/reboot"&gt;@reboot&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Run once at system startup (not a true time expression)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  3. Common Schedule Examples
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Here are real-world cron expressions organized by use case. Copy-paste these into
      your crontab and adjust as needed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Every Minute / High Frequency
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expression&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;* * * * *&lt;/td&gt;
&lt;td&gt;Every minute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;*/5 * * * *&lt;/td&gt;
&lt;td&gt;Every 5 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;*/10 * * * *&lt;/td&gt;
&lt;td&gt;Every 10 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;*/15 * * * *&lt;/td&gt;
&lt;td&gt;Every 15 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;*/30 * * * *&lt;/td&gt;
&lt;td&gt;Every 30 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Hourly / Every N Hours
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expression&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0 * * * *&lt;/td&gt;
&lt;td&gt;Every hour at minute 0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 */2 * * *&lt;/td&gt;
&lt;td&gt;Every 2 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 */3 * * *&lt;/td&gt;
&lt;td&gt;Every 3 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 */6 * * *&lt;/td&gt;
&lt;td&gt;Every 6 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 */12 * * *&lt;/td&gt;
&lt;td&gt;Every 12 hours&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Daily Schedules
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expression&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0 0 * * *&lt;/td&gt;
&lt;td&gt;Daily at midnight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30 5 * * *&lt;/td&gt;
&lt;td&gt;Daily at 5:30 AM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 2 * * *&lt;/td&gt;
&lt;td&gt;Daily at 2:00 AM (common for maintenance)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 22 * * *&lt;/td&gt;
&lt;td&gt;Daily at 10:00 PM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 8,12,17 * * *&lt;/td&gt;
&lt;td&gt;Daily at 8 AM, 12 PM, and 5 PM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 9-17 * * *&lt;/td&gt;
&lt;td&gt;Every hour from 9 AM to 5 PM (business hours)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Weekly / Weekday Schedules
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expression&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0 0 * * 0&lt;/td&gt;
&lt;td&gt;Every Sunday at midnight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 9 * * 1&lt;/td&gt;
&lt;td&gt;Every Monday at 9 AM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 0 * * 1-5&lt;/td&gt;
&lt;td&gt;Every weekday at midnight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 9 * * 1-5&lt;/td&gt;
&lt;td&gt;Weekdays at 9 AM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 18 * * 5&lt;/td&gt;
&lt;td&gt;Every Friday at 6 PM&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 0 * * 6,0&lt;/td&gt;
&lt;td&gt;Weekends at midnight&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Monthly / Advanced Schedules
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Expression&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0 0 1 * *&lt;/td&gt;
&lt;td&gt;First day of every month at midnight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 0 15 * *&lt;/td&gt;
&lt;td&gt;15th of every month at midnight&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 0 L * *&lt;/td&gt;
&lt;td&gt;Last day of every month (Quartz), or at midnight on the 31st (Unix)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 0 1 1 *&lt;/td&gt;
&lt;td&gt;January 1st (yearly)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 0 1 */3 *&lt;/td&gt;
&lt;td&gt;First day of every quarter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 0 ? * MON#1&lt;/td&gt;
&lt;td&gt;First Monday of every month (Quartz)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 0 ? * FRI#3&lt;/td&gt;
&lt;td&gt;Third Friday of every month (Quartz)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0 0 15W * *&lt;/td&gt;
&lt;td&gt;Nearest weekday to the 15th (Quartz)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  4. Crontab Quick Reference
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      The `crontab` command manages your cron jobs. Each
      user has their own crontab file.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;crontab -e&lt;/td&gt;
&lt;td&gt;Edit your crontab file (opens in default editor)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;crontab -l&lt;/td&gt;
&lt;td&gt;List your current cron jobs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;crontab -r&lt;/td&gt;
&lt;td&gt;Remove your crontab file (deletes all jobs!)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;crontab -u user -l&lt;/td&gt;
&lt;td&gt;List another user's crontab (root only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;crontab /path/to/file&lt;/td&gt;
&lt;td&gt;Install a crontab from a file&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      A crontab entry has this format:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ┌───────────── minute (0-59)&lt;/span&gt;
&lt;span class="c"&gt;# │ ┌───────────── hour (0-23)&lt;/span&gt;
&lt;span class="c"&gt;# │ │ ┌───────────── day of month (1-31)&lt;/span&gt;
&lt;span class="c"&gt;# │ │ │ ┌───────────── month (1-12)&lt;/span&gt;
&lt;span class="c"&gt;# │ │ │ │ ┌───────────── day of week (0-7, 0 or 7 = Sunday)&lt;/span&gt;
&lt;span class="c"&gt;# │ │ │ │ │&lt;/span&gt;
&lt;span class="c"&gt;# * * * * *  command_to_run&lt;/span&gt;

&lt;span class="c"&gt;# Example: backup database every day at 2:30 AM&lt;/span&gt;
30 2 * * * /usr/local/bin/backup.sh

&lt;span class="c"&gt;# Example: send a report every Monday at 9 AM&lt;/span&gt;
0 9 * * 1 /usr/local/bin/send-report.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Timezone Considerations
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Standard Unix cron uses the **system timezone**.
      This is one of the most common sources of confusion — especially when your server
      is in UTC and you expect a local time.




      -
        **Unix cron** reads the system's timezone
        (set via `/etc/timezone` or the TZ environment variable).
        You can set `TZ=America/New_York` at the top of your
        crontab to run jobs in a specific timezone.


      -
        **Systemd timers** use the system timezone.
        Check with `timedatectl`.


      -
        **AWS EventBridge** supports setting a timezone
        per rule. The default is UTC.


      -
        **Google Cloud Scheduler** requires you to specify
        the timezone explicitly (e.g., `America/New_York`).


      -
        **Kubernetes CronJobs** run in the timezone of the
        kube-controller-manager. As of Kubernetes 1.27+, you can set
        `spec.timeZone` in the CronJob spec.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;⚠️ Daylight Saving Time&lt;/strong&gt; Cron jobs running during DST transitions can behave unexpectedly:&lt;br&gt;
 Spring forward — if you schedule a job at&lt;br&gt;
 2:30 AM, it won't run because that time doesn't exist.&lt;br&gt;
 Fall back — a job at 1:30 AM may run twice.&lt;br&gt;
 To avoid this, schedule critical jobs in UTC or choose times outside the DST window&lt;br&gt;
 (e.g., 3 AM for daily tasks).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  6. Troubleshooting
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Cron jobs can fail silently. Here are the most common issues and how to fix them.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Solution&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Job never runs&lt;/td&gt;
&lt;td&gt;Check the system timezone. Run &lt;code&gt;date&lt;/code&gt; to verify. Test with &lt;code&gt;*/1 * * * * echo "test" &amp;gt;&amp;gt; /tmp/cron-test.log&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Job runs but does nothing&lt;/td&gt;
&lt;td&gt;Cron runs with a limited PATH (~/usr/bin:/bin). Always use &lt;strong&gt;absolute paths&lt;/strong&gt; to commands and scripts. Or set &lt;code&gt;PATH=/usr/local/bin:/usr/bin:/bin&lt;/code&gt; at the top of your crontab.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No log output&lt;/td&gt;
&lt;td&gt;Redirect output: &lt;code&gt;* * * * * /script.sh &amp;gt;&amp;gt; /var/log/cron.log 2&amp;gt;&amp;amp;1&lt;/code&gt;. Cron emails output by default (check &lt;code&gt;MAILTO&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Job runs at wrong time&lt;/td&gt;
&lt;td&gt;Check timezone: `timedatectl \&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Permission denied&lt;/td&gt;
&lt;td&gt;Make the script executable: {% raw %}&lt;code&gt;chmod +x /path/to/script.sh&lt;/code&gt;. Check that the cron user has execution rights.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"bad minute" syntax error&lt;/td&gt;
&lt;td&gt;Check for invisible characters, trailing spaces, or tab issues. Validate with &lt;code&gt;crontab -e&lt;/code&gt; which does basic syntax checking.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Environment variables not set&lt;/td&gt;
&lt;td&gt;Cron runs in a minimal environment. Source your profile: &lt;code&gt;* * * * * . $HOME/.profile; /script.sh&lt;/code&gt;. Or set variables directly in crontab.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Job runs multiple times&lt;/td&gt;
&lt;td&gt;Check for duplicate crontab entries. Use &lt;code&gt;crontab -l&lt;/code&gt; to verify. Also check system cron directories like &lt;code&gt;/etc/cron.d/&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Debugging Checklist
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      - Verify the cron daemon is running: `systemctl status cron` or `ps aux | grep cron`

      - Check system timezone: `timedatectl` or `date +%Z`

      - List your crontab: `crontab -l`

      - Add a simple test job that writes to a file every minute

      - Check cron logs: `grep cron /var/log/syslog` or `/var/log/cron`

      - Ensure the script is executable and uses absolute paths

      - Redirect stdout and stderr to a log file for debugging
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h2&gt;
  
  
  7. Cron in the Cloud
&lt;/h2&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Cloud-native schedulers use cron-like syntax with some differences. Here's how
      each platform handles it:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AWS EventBridge&lt;/td&gt;
&lt;td&gt;cron(0 12 * * ? *)&lt;/td&gt;
&lt;td&gt;Uses 6-field Quartz format (adds year). Must have &lt;code&gt;?&lt;/code&gt; for either day-of-month or day-of-week&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google Cloud Scheduler&lt;/td&gt;
&lt;td&gt;0 12 * * *&lt;/td&gt;
&lt;td&gt;Standard 5-field Unix format. Timezone must be specified separately&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Azure Scheduler&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Uses JSON with &lt;code&gt;schedule&lt;/code&gt; property. Supports cron expressions with 6 fields including seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kubernetes CronJob&lt;/td&gt;
&lt;td&gt;0 12 * * *&lt;/td&gt;
&lt;td&gt;Standard 5-field Unix format. &lt;code&gt;spec.timeZone&lt;/code&gt; available in k8s 1.27+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;td&gt;cron: '0 12 * * *'&lt;/td&gt;
&lt;td&gt;Standard 5-field format. Uses UTC. Add &lt;code&gt;timezone: America/New_York&lt;/code&gt; for other zones&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  8. Alternative Notations
&lt;/h2&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Some systems extend cron syntax with additional fields or alternative formats:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  6-Field (Quartz) Format
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Quartz schedulers (common in Java / Spring Boot) add a seconds field at the beginning
      and an optional year field at the end:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ┌───────────── second (0-59)&lt;/span&gt;
&lt;span class="c"&gt;# │ ┌───────────── minute (0-59)&lt;/span&gt;
&lt;span class="c"&gt;# │ │ ┌───────────── hour (0-23)&lt;/span&gt;
&lt;span class="c"&gt;# │ │ │ ┌───────────── day of month (1-31)&lt;/span&gt;
&lt;span class="c"&gt;# │ │ │ │ ┌───────────── month (1-12)&lt;/span&gt;
&lt;span class="c"&gt;# │ │ │ │ │ ┌───────────── day of week (1-7, 1 = Sunday)&lt;/span&gt;
&lt;span class="c"&gt;# │ │ │ │ │ │&lt;/span&gt;
&lt;span class="c"&gt;# * * * * * *  command&lt;/span&gt;

&lt;span class="c"&gt;# Example: run at 10:15 AM every day&lt;/span&gt;
0 15 10 * * ?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Common Mistakes &amp;amp; How to Avoid Them
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;      Most cron incidents aren't syntax errors — they're environment&lt;br&gt;
      mismatches between your shell and cron's minimal runtime. These are&lt;br&gt;
      the five that bite developers most often in production.
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  -
    **Assuming cron uses your local timezone.**
    Cron uses the *system* timezone, not your shell's
    `TZ` or locale. Verify with
    `timedatectl`. To force a zone, put
    `CRON_TZ=America/New_York` at the top of your
    crontab (Vixie cron), or schedule in UTC and convert.


  -
    **Using relative paths.**
    Cron's default `PATH` is minimal
    (`/usr/bin:/bin`), so
    `node`, `python3`,
    and project binaries often aren't found. Use absolute paths to both the
    interpreter and the script, or set
    `PATH=/usr/local/bin:/usr/bin:/bin` at the top
    of the crontab.


  -
    **Forgetting to escape `%`.**
    In a crontab, `%` is translated to a newline.
    A command like `date +%Y-%m-%d` silently
    breaks — write it as `date +\%Y-\%m-\%d`.


  -
    **Combining day-of-month and day-of-week.**
    The two fields are *OR'd*, not AND'd:
    `0 0 1 * 1` runs on the 1st of the month
    * and* every Monday — twice as often as intended. Use
    `?` in Quartz-style schedulers, or split into
    two separate jobs.


  -
    **Scripts that aren't executable.**
    If your script lacks `chmod +x` or a valid
    shebang, cron fails silently — no email, no log entry. Always run
    `chmod +x /path/to/script.sh` and test the
    script manually before wiring it into cron.
&lt;/code&gt;&lt;/pre&gt;

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

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Frequently Asked Questions&lt;br&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What's the difference between * and ? in cron expressions?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;means "every value" in a
            field. ? is a Quartz-specific (6-field)
            character meaning "no specific value" — used in either
            day-of-month or day-of-week so the two never conflict, e.g.
            0 0 12 ? * MON. Standard 5-field Unix
            cron does not support ?; use
            * there.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why didn't my cron job run?
&lt;/h3&gt;

&lt;p&gt;Check, in order: the daemon is running (systemctl status cron),&lt;br&gt;
                the timezone matches your expectation (date),&lt;br&gt;
                the script is executable and uses absolute paths, and the logs show an&lt;br&gt;
                attempt (grep cron /var/log/syslog). Add&lt;br&gt;
                a test job — * * * * * echo hi &amp;gt;&amp;gt; /tmp/cron-test.log&lt;br&gt;
                — to isolate whether the problem is cron itself or your command.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I run a job every 30 minutes?
&lt;/h3&gt;

&lt;p&gt;Use the step operator in the minute field:&lt;br&gt;
                */30 * * * * command. Likewise&lt;br&gt;
                */15 * * * * for every 15 minutes and&lt;br&gt;
                0 */2 * * * for every 2 hours on the hour.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is @daily the same as 0 0 * * *?
&lt;/h3&gt;

&lt;p&gt;Yes — both run at midnight every day. @daily&lt;br&gt;
                is a special string alias. The family includes&lt;br&gt;
                @hourly, &lt;a class="mentioned-user" href="https://dev.to/midnight"&gt;@midnight&lt;/a&gt;,&lt;br&gt;
                @weekly, @monthly,&lt;br&gt;
                @yearly, and&lt;br&gt;
                &lt;a class="mentioned-user" href="https://dev.to/reboot"&gt;@reboot&lt;/a&gt;, which runs once when the cron&lt;br&gt;
                daemon starts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why did my cron job run twice or at the wrong time?
&lt;/h3&gt;

&lt;p&gt;The usual culprits: duplicate entries in crontab -l,&lt;br&gt;
                the same job also defined in /etc/cron.d/ or&lt;br&gt;
                /etc/crontab, DST fall-back running the&lt;br&gt;
                job twice, or a system timezone different from the one you assumed. Run&lt;br&gt;
                crontab -l and&lt;br&gt;
                timedatectl to rule them out.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🔍 Related Resources&lt;/strong&gt; Check out our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/tools/timestamp" rel="noopener noreferrer"&gt;&lt;br&gt;
 Unix Timestamp Converter&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 for converting cron execution times, and our&lt;br&gt;
 &lt;a href="https://devtoolshub.cloud/blog/timestamp-cheat-sheet" rel="noopener noreferrer"&gt;&lt;br&gt;
 Unix Timestamp Cheat Sheet&lt;br&gt;
 &lt;/a&gt;&lt;br&gt;
 for working with dates and times across programming languages.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>CSS Units Cheat Sheet: px, em, rem, vh, and When to Use Each</title>
      <dc:creator>kingfujing</dc:creator>
      <pubDate>Thu, 12 Nov 2026 01:53:41 +0000</pubDate>
      <link>https://dev.to/kingfujing/css-units-cheat-sheet-px-em-rem-vh-and-when-to-use-each-1io6</link>
      <guid>https://dev.to/kingfujing/css-units-cheat-sheet-px-em-rem-vh-and-when-to-use-each-1io6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://devtoolshub.cloud/blog/css-units-cheat-sheet" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — free, privacy-first online tools for developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;CSS units can be confusing. Should you use &lt;code&gt;px&lt;/code&gt; or &lt;code&gt;rem&lt;/code&gt;? When does &lt;code&gt;vw&lt;/code&gt; make sense? What about &lt;code&gt;ch&lt;/code&gt; and &lt;code&gt;ex&lt;/code&gt;? Picking the right unit makes the difference between a layout that breaks and one that gracefully adapts to every screen size.&lt;/p&gt;

&lt;p&gt;This reference breaks CSS units into two categories — &lt;strong&gt;absolute&lt;/strong&gt; and &lt;strong&gt;relative&lt;/strong&gt; — with clear examples of when to use each. Bookmark this page for your next responsive design project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Quick Rule of Thumb&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;rem&lt;/code&gt; for font sizes, &lt;code&gt;px&lt;/code&gt; for borders/shadows, &lt;code&gt;%&lt;/code&gt; for widths, &lt;code&gt;vw/vh&lt;/code&gt; for full-screen sections, and &lt;code&gt;em&lt;/code&gt; for spacing relative to the current font size.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Absolute Units
&lt;/h2&gt;

&lt;p&gt;Absolute units are fixed-length values. They don't scale with the viewport, parent element, or font size. Use them for print stylesheets, borders, and situations where precision matters regardless of screen size.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Unit&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Relative to&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;px&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pixel&lt;/td&gt;
&lt;td&gt;1px = 1/96th of 1 inch (screen)&lt;/td&gt;
&lt;td&gt;Borders, shadows, small precise spacing, images&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Point&lt;/td&gt;
&lt;td&gt;1pt = 1/72nd of 1 inch&lt;/td&gt;
&lt;td&gt;Print stylesheets, traditional typography&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pica&lt;/td&gt;
&lt;td&gt;1pc = 12pt = 1/6th of 1 inch&lt;/td&gt;
&lt;td&gt;Print layouts (rarely used on web)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Centimeter&lt;/td&gt;
&lt;td&gt;1cm = 37.8px (approx)&lt;/td&gt;
&lt;td&gt;Print stylesheets, physical measurements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mm&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Millimeter&lt;/td&gt;
&lt;td&gt;1mm = 1/10th of 1cm&lt;/td&gt;
&lt;td&gt;Print stylesheets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;in&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inch&lt;/td&gt;
&lt;td&gt;1in = 96px&lt;/td&gt;
&lt;td&gt;Print stylesheets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Q&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Quarter-millimeter&lt;/td&gt;
&lt;td&gt;1Q = 1/40th of 1cm&lt;/td&gt;
&lt;td&gt;Print, Japanese/CJK layouts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;When Not to Use px&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Avoid &lt;code&gt;px&lt;/code&gt; for font sizes in modern responsive design. Users who change their browser's default font size will see no change in pixel-sized text, which creates accessibility issues. Use &lt;code&gt;rem&lt;/code&gt; instead — it respects the user's font size preference.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Relative Units
&lt;/h2&gt;

&lt;p&gt;Relative units scale based on the context — the viewport, parent element, or root font size. They are the foundation of responsive and accessible design.&lt;/p&gt;

&lt;h3&gt;
  
  
  Font-Relative Units
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Unit&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Relative to&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;em&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Em&lt;/td&gt;
&lt;td&gt;Font size of the parent element&lt;/td&gt;
&lt;td&gt;Spacing, padding, margins relative to text size&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Root Em&lt;/td&gt;
&lt;td&gt;Font size of the root (&lt;code&gt;&amp;lt;html&amp;gt;&lt;/code&gt;) element&lt;/td&gt;
&lt;td&gt;Font sizes, spacing (accessibility-friendly)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Character&lt;/td&gt;
&lt;td&gt;Width of the '0' character in current font&lt;/td&gt;
&lt;td&gt;Input widths, line length constraints&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ex&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;X-height&lt;/td&gt;
&lt;td&gt;Height of the 'x' character in current font&lt;/td&gt;
&lt;td&gt;Vertical alignment, inline spacing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ic&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ideograph&lt;/td&gt;
&lt;td&gt;Width of CJK ideograph character&lt;/td&gt;
&lt;td&gt;Chinese/Japanese/Korean text layouts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Line height&lt;/td&gt;
&lt;td&gt;Computed line-height of the element&lt;/td&gt;
&lt;td&gt;Vertical rhythm, consistent spacing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rlh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Root line height&lt;/td&gt;
&lt;td&gt;Computed line-height of the root element&lt;/td&gt;
&lt;td&gt;Global vertical rhythm&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Viewport-Relative Units
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Unit&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Relative to&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vw&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Viewport Width&lt;/td&gt;
&lt;td&gt;1% of viewport width&lt;/td&gt;
&lt;td&gt;Full-width elements, hero sections, fluid typography&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Viewport Height&lt;/td&gt;
&lt;td&gt;1% of viewport height&lt;/td&gt;
&lt;td&gt;Full-height sections, modal overlays, sticky elements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vmin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Viewport Minimum&lt;/td&gt;
&lt;td&gt;1% of the smaller viewport dimension (width or height)&lt;/td&gt;
&lt;td&gt;Responsive square elements, safe sizing for all orientations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vmax&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Viewport Maximum&lt;/td&gt;
&lt;td&gt;1% of the larger viewport dimension (width or height)&lt;/td&gt;
&lt;td&gt;Full-screen backgrounds, decorative elements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;svw&lt;/code&gt; / &lt;code&gt;svh&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Small Viewport&lt;/td&gt;
&lt;td&gt;Viewport size excluding dynamic browser chrome&lt;/td&gt;
&lt;td&gt;Mobile-safe full-screen layouts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;lvw&lt;/code&gt; / &lt;code&gt;lvh&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Large Viewport&lt;/td&gt;
&lt;td&gt;Viewport size including potential browser chrome&lt;/td&gt;
&lt;td&gt;When you want the full device screen regardless of UI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;dvw&lt;/code&gt; / &lt;code&gt;dvh&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Dynamic Viewport&lt;/td&gt;
&lt;td&gt;Dynamically updates as browser chrome shows/hides&lt;/td&gt;
&lt;td&gt;Works like 100vh but handles mobile toolbar changes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Viewport Unit Gotcha on Mobile&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On iOS Safari, &lt;code&gt;100vh&lt;/code&gt; includes the browser toolbar height, which collapses when scrolling. This causes content to be taller than expected. Use &lt;code&gt;100dvh&lt;/code&gt; (dynamic viewport height) or &lt;code&gt;100svh&lt;/code&gt; (small viewport height) for reliable full-height sections on mobile.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Percentage Unit
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Unit&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Relative to&lt;/th&gt;
&lt;th&gt;Best For&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Percentage&lt;/td&gt;
&lt;td&gt;Depends on property: width → parent width, height → parent height, font-size → parent font-size, padding/margin → &lt;strong&gt;parent width&lt;/strong&gt; (even for vertical padding)&lt;/td&gt;
&lt;td&gt;Fluid layouts, responsive widths, aspect ratios&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Percentage Padding Quirk&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When using &lt;code&gt;padding-top: 50%&lt;/code&gt; or &lt;code&gt;padding-bottom: 50%&lt;/code&gt;, the percentage is calculated from the &lt;strong&gt;parent's width&lt;/strong&gt;, not height. This is actually useful for creating fixed-aspect-ratio boxes (like a 16:9 container) without JavaScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  When to Use Each Unit
&lt;/h2&gt;

&lt;p&gt;The table below maps common CSS properties to their recommended units.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Recommended Unit&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;font-size&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Respects user's browser font size setting. Avoids compounding issues of em.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;padding / margin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Consistent spacing regardless of nested font sizes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;width / max-width&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;% or rem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;% for fluid layouts, rem for fixed content widths (e.g., article max-width).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;height&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;auto (avoid fixed)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Let content determine height. Use min-height with vh for full-screen sections.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;border-width&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;px&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Borders should be crisp and not scale with text size.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;border-radius&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;px or rem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;px for small radii, rem for larger rounded corners that should scale.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;box-shadow&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;px&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Shadow blur and spread should stay crisp.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;line-height&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;unitless (e.g., 1.5)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unitless values scale proportionally with font-size changes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rem&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Grid/flexbox gaps should scale with content size.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;hero / full-screen&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;dvh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Dynamic viewport handles mobile browser toolbar correctly.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fluid typography&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;clamp()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Combine rem + vw with min/max bounds (e.g., clamp(1rem, 2.5vw, 2rem)).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;icon sizing&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;em&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Icon scales with surrounding text size automatically.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Practical Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Fluid Typography with clamp()
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;clamp()&lt;/code&gt; CSS function lets you set a font size that scales between a minimum and maximum value. This is the modern way to do responsive typography without media queries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* Fluid heading: scales from 1.5rem to 3rem between 320px and 1200px viewports */&lt;/span&gt;
&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1rem&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;2.5vw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/* Fluid body text */&lt;/span&gt;
&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.875rem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.75rem&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.5vw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.125rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Full-Height Hero Section (Mobile-Safe)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.hero&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* dvh = dynamic viewport height — handles mobile browser toolbar */&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100dvh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="cm"&gt;/* Fallback for older browsers */&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100svh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Consistent Spacing with rem
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nt"&gt;root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* Set root font size. Browser default is 16px = 1rem */&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="kt"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* Respects user preferences */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.card&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="cm"&gt;/* = 24px at default font size */&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* = 16px */&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* = 8px */&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="cm"&gt;/* = 12px grid gap */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.25rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* = 20px */&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* relative to h2 font size */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  16:9 Aspect Ratio Box
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.aspect-16-9&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* Padding % is calculated from parent width */&lt;/span&gt;
  &lt;span class="cm"&gt;/* 9/16 = 56.25% */&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="kt"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;56.25&lt;/span&gt;&lt;span class="kt"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;relative&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.aspect-16-9&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="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;inset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="kt"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="kt"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;object-fit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Perfectly Centered Modal
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.modal-overlay&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;inset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.modal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;90vw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;600px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="cm"&gt;/* 90% of viewport width, max 600px */&lt;/span&gt;
  &lt;span class="nl"&gt;max-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90dvh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="cm"&gt;/* 90% of dynamic viewport height */&lt;/span&gt;
  &lt;span class="nl"&gt;overflow-y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.75rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  calc() in Practice
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;calc()&lt;/code&gt; function lets you mix units freely. It's extremely useful for fluid layouts where you need arithmetic operations on CSS values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="cm"&gt;/* Sidebar + main: 250px sidebar, rest is main */&lt;/span&gt;
&lt;span class="nc"&gt;.main-layout&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;250px&lt;/span&gt; &lt;span class="mi"&gt;1fr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/* Full-width container with fixed gutters */&lt;/span&gt;
&lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="kt"&gt;%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;3rem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-inline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/* Fluid typography alternative */&lt;/span&gt;
&lt;span class="nt"&gt;h1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.5rem&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2vw&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="cm"&gt;/* Height minus header */&lt;/span&gt;
&lt;span class="nc"&gt;.content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;min-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100dvh&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;4rem&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="cm"&gt;/* Background that extends beyond content area */&lt;/span&gt;
&lt;span class="nc"&gt;.hero&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100vw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;-50vw&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="kt"&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;h2&gt;
  
  
  Unit Comparison Table
&lt;/h2&gt;

&lt;p&gt;A quick comparison of how different units behave at different scales. Assumes root font size of 16px and a 1200px wide viewport.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;px&lt;/th&gt;
&lt;th&gt;rem&lt;/th&gt;
&lt;th&gt;em (parent 16px)&lt;/th&gt;
&lt;th&gt;vw (1200px)&lt;/th&gt;
&lt;th&gt;%&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Small&lt;/td&gt;
&lt;td&gt;8px&lt;/td&gt;
&lt;td&gt;0.5rem&lt;/td&gt;
&lt;td&gt;0.5em&lt;/td&gt;
&lt;td&gt;0.67vw&lt;/td&gt;
&lt;td&gt;0.67%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Body&lt;/td&gt;
&lt;td&gt;16px&lt;/td&gt;
&lt;td&gt;1rem&lt;/td&gt;
&lt;td&gt;1em&lt;/td&gt;
&lt;td&gt;1.33vw&lt;/td&gt;
&lt;td&gt;1.33%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;24px&lt;/td&gt;
&lt;td&gt;1.5rem&lt;/td&gt;
&lt;td&gt;1.5em&lt;/td&gt;
&lt;td&gt;2vw&lt;/td&gt;
&lt;td&gt;2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Large&lt;/td&gt;
&lt;td&gt;32px&lt;/td&gt;
&lt;td&gt;2rem&lt;/td&gt;
&lt;td&gt;2em&lt;/td&gt;
&lt;td&gt;2.67vw&lt;/td&gt;
&lt;td&gt;2.67%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heading&lt;/td&gt;
&lt;td&gt;48px&lt;/td&gt;
&lt;td&gt;3rem&lt;/td&gt;
&lt;td&gt;3em&lt;/td&gt;
&lt;td&gt;4vw&lt;/td&gt;
&lt;td&gt;4%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;🎯 &lt;strong&gt;Summary: Unit Decision Flow&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;font-size&lt;/strong&gt; → &lt;code&gt;rem&lt;/code&gt; (or &lt;code&gt;clamp()&lt;/code&gt; for fluid scaling)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;spacing (padding, margin, gap)&lt;/strong&gt; → &lt;code&gt;rem&lt;/code&gt; (consistent everywhere)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;widths&lt;/strong&gt; → &lt;code&gt;%&lt;/code&gt; (fluid), &lt;code&gt;rem&lt;/code&gt; (fixed content), &lt;code&gt;min()&lt;/code&gt; (max bound)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;heights&lt;/strong&gt; → &lt;code&gt;auto&lt;/code&gt; (preferred), &lt;code&gt;dvh&lt;/code&gt; (full-screen)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;borders / shadows&lt;/strong&gt; → &lt;code&gt;px&lt;/code&gt; (keep them crisp)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;icon sizes&lt;/strong&gt; → &lt;code&gt;em&lt;/code&gt; (scale with text)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;line-height&lt;/strong&gt; → unitless number (always)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fluid typography&lt;/strong&gt; → &lt;code&gt;clamp()&lt;/code&gt; with &lt;code&gt;rem&lt;/code&gt; and &lt;code&gt;vw&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;full viewport sections&lt;/strong&gt; → &lt;code&gt;100dvh&lt;/code&gt; (dynamic) or &lt;code&gt;100svh&lt;/code&gt; (small)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;mixed calculations&lt;/strong&gt; → &lt;code&gt;calc()&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Common Mistakes &amp;amp; How to Avoid Them
&lt;/h2&gt;

&lt;p&gt;CSS units seem simple until a layout breaks. These are the mistakes developers make most often — and the fixes that prevent them.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Using px for Font Sizes Hurts Accessibility
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;px&lt;/code&gt; font sizes ignore the user's browser font-size setting, so users who increase their default font size (often for vision reasons) see no change on your site. Use &lt;code&gt;rem&lt;/code&gt; for font sizes — it scales with the root font size — and reserve &lt;code&gt;px&lt;/code&gt; for borders, shadows, and 1px hairline rules that should stay crisp.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Confusing em with rem
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;rem&lt;/code&gt; is always relative to the root element font size (usually 16px), so it is predictable anywhere in the tree. &lt;code&gt;em&lt;/code&gt; is relative to the &lt;em&gt;current&lt;/em&gt; element's font size, and because it compounds, nested elements can produce surprising sizes: a &lt;code&gt;1.5em&lt;/code&gt; padding inside a &lt;code&gt;1.5em&lt;/code&gt; font becomes &lt;code&gt;2.25em&lt;/code&gt; of effective spacing. Use &lt;code&gt;rem&lt;/code&gt; for global spacing and typography; use &lt;code&gt;em&lt;/code&gt; deliberately when a component should scale with its own font size (icons, button padding).&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Using 100vh for Mobile Full-Height Sections
&lt;/h3&gt;

&lt;p&gt;On mobile browsers, &lt;code&gt;100vh&lt;/code&gt; refers to the &lt;strong&gt;largest&lt;/strong&gt; viewport, which includes the area hidden behind the URL bar — so a &lt;code&gt;100vh&lt;/code&gt; section gets cut off or causes scroll jumps when the bar collapses. Use &lt;code&gt;100dvh&lt;/code&gt; (dynamic viewport height) for mobile full-height layouts, with &lt;code&gt;100svh&lt;/code&gt; as a fallback for older browsers.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Using vw for Font Sizes Without clamp()
&lt;/h3&gt;

&lt;p&gt;A headline set to &lt;code&gt;4vw&lt;/code&gt; looks great on desktop but becomes unreadably small on phones and comically huge on ultrawide monitors. Wrap viewport units in &lt;code&gt;clamp()&lt;/code&gt; with &lt;code&gt;rem&lt;/code&gt; bounds: &lt;code&gt;font-size: clamp(1.5rem, 4vw, 3rem)&lt;/code&gt;. This gives you fluid scaling without ever crossing accessibility limits.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Expecting Percentage Heights to "Just Work"
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;height: 50%&lt;/code&gt; only works when the parent has an explicit height (not &lt;code&gt;auto&lt;/code&gt;). A common trap is setting a child to &lt;code&gt;100%&lt;/code&gt; inside a parent whose height comes from content — the percentage resolves to &lt;code&gt;auto&lt;/code&gt; and the layout collapses. If the parent's height is content-driven, use flexbox/grid stretch, &lt;code&gt;min-height&lt;/code&gt;, or viewport units instead of percentages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is the difference between px and rem?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;px&lt;/code&gt; is an absolute unit — 1px is 1/96th of an inch on screen — so it never changes regardless of browser settings. &lt;code&gt;rem&lt;/code&gt; is relative to the root element font size (usually 16px, so &lt;code&gt;1rem&lt;/code&gt; = 16px). Because &lt;code&gt;rem&lt;/code&gt; scales when users change their browser's default font size, it is the recommended unit for font sizes, padding, and margin. Use &lt;code&gt;px&lt;/code&gt; for borders and shadows that must stay visually identical at any zoom level.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between em and rem?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;rem&lt;/code&gt; is relative to the &lt;strong&gt;root&lt;/strong&gt; element font size, so &lt;code&gt;1rem&lt;/code&gt; is the same everywhere in the document. &lt;code&gt;em&lt;/code&gt; is relative to the &lt;strong&gt;current element's&lt;/strong&gt; font size, and it compounds through nesting — a &lt;code&gt;2em&lt;/code&gt; margin inside a &lt;code&gt;1.5em&lt;/code&gt; font resolves to &lt;code&gt;3em&lt;/code&gt;. This makes &lt;code&gt;em&lt;/code&gt; great for components that should scale with their own text (icon sizes, button padding) and &lt;code&gt;rem&lt;/code&gt; better for site-wide spacing and typography.&lt;/p&gt;

&lt;h3&gt;
  
  
  When should I use vw and vh?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;vw&lt;/code&gt; and &lt;code&gt;vh&lt;/code&gt; are 1% of the viewport width and height. Use them for full-screen hero sections, overlays, and fluid typography inside &lt;code&gt;clamp()&lt;/code&gt;. Avoid raw &lt;code&gt;vh&lt;/code&gt; for mobile heights — the URL bar changes the visible viewport, so use &lt;code&gt;100dvh&lt;/code&gt; (dynamic) or &lt;code&gt;100svh&lt;/code&gt; (small) instead. For widths, prefer &lt;code&gt;%&lt;/code&gt; when the size should relate to a container rather than the whole viewport.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I use px or rem for font sizes?
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;rem&lt;/code&gt;. Because &lt;code&gt;rem&lt;/code&gt; is relative to the root font size, it respects the user's browser font-size preference — a core accessibility requirement. &lt;code&gt;px&lt;/code&gt; ignores that setting, which can make your text impossible to resize for users with low vision. A common pattern is setting the root font size in &lt;code&gt;rem&lt;/code&gt; (or leaving it at the default 16px) and sizing everything else in &lt;code&gt;rem&lt;/code&gt;, with &lt;code&gt;clamp()&lt;/code&gt; for fluid type.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between vh, svh, lvh, and dvh?
&lt;/h3&gt;

&lt;p&gt;These are the four viewport-height units. &lt;code&gt;vh&lt;/code&gt; equals 1% of the &lt;strong&gt;largest&lt;/strong&gt; viewport — on mobile that includes the area hidden behind the browser UI. &lt;code&gt;svh&lt;/code&gt; is the &lt;strong&gt;small&lt;/strong&gt; viewport (visible area when the URL bar is shown), &lt;code&gt;lvh&lt;/code&gt; is the &lt;strong&gt;large&lt;/strong&gt; viewport (URL bar hidden), and &lt;code&gt;dvh&lt;/code&gt; is the &lt;strong&gt;dynamic&lt;/strong&gt; viewport, which updates live as the browser UI expands and collapses. For mobile full-height sections, &lt;code&gt;100dvh&lt;/code&gt; gives the smoothest behavior, with &lt;code&gt;100svh&lt;/code&gt; as a fallback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;If this cheat sheet helped you clean up your CSS, try the free developer tools on DevToolsHub. The &lt;a href="https://devtoolshub.cloud/tools/color-converter" rel="noopener noreferrer"&gt;Color Converter&lt;/a&gt; is handy when you're writing CSS that mixes &lt;code&gt;hex&lt;/code&gt;, &lt;code&gt;rgb()&lt;/code&gt;, and &lt;code&gt;hsl()&lt;/code&gt; values alongside your unit choices, and the &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;JSON Formatter&lt;/a&gt; is a quick way to tidy up the design tokens and theme config files where your spacing and typography scales live. Both run entirely in your browser — no sign-up, no tracking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related Tools:&lt;/strong&gt; &lt;a href="https://devtoolshub.cloud/tools/color-converter" rel="noopener noreferrer"&gt;Color Converter&lt;/a&gt; · &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;JSON Formatter&lt;/a&gt; · &lt;a href="https://devtoolshub.cloud/tools/base64" rel="noopener noreferrer"&gt;Base64 Encoder/Decoder&lt;/a&gt; · &lt;a href="https://devtoolshub.cloud/tools/regex-tester" rel="noopener noreferrer"&gt;Regex Tester&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Git Commands Cheat Sheet: The Commands You Actually Use Daily</title>
      <dc:creator>kingfujing</dc:creator>
      <pubDate>Thu, 12 Nov 2026 01:52:36 +0000</pubDate>
      <link>https://dev.to/kingfujing/git-commands-cheat-sheet-the-commands-you-actually-use-daily-50ll</link>
      <guid>https://dev.to/kingfujing/git-commands-cheat-sheet-the-commands-you-actually-use-daily-50ll</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://devtoolshub.cloud/blog/git-commands-cheat-sheet" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — free, privacy-first online tools for developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Git is the backbone of modern software development, but its command surface is vast. Even experienced developers reach for documentation daily. This cheat sheet covers the essential Git commands you'll use every day — from initializing a repository to interactive rebase and everything in between.&lt;/p&gt;

&lt;p&gt;Each section groups related commands with common options, flags, and practical examples. Bookmark this page and come back whenever you need to remember the exact syntax for a tricky operation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚡ &lt;strong&gt;Quick Tip&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use &lt;code&gt;git status&lt;/code&gt; constantly. It's the safest command in Git — it tells you exactly what's going on without changing anything.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. Setup &amp;amp; Configuration
&lt;/h2&gt;

&lt;p&gt;Configure your Git identity and preferences. These are the first commands you run on a new machine.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a new Git repository in the current directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git clone &amp;lt;url&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Clone an existing repository from a remote URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git config --global user.name "Name"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Set your global Git username for all commits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git config --global user.email "email@example.com"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Set your global Git email for all commits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git config --global core.editor "code --wait"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Set VS Code as your Git editor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git config --global init.defaultBranch main&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Set default branch name to "main" instead of "master"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git config --list&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show all configured Git settings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git config --global alias.st status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create an alias: &lt;code&gt;git st&lt;/code&gt; = &lt;code&gt;git status&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Pro tip:&lt;/strong&gt; Set up aliases early. Common ones include &lt;code&gt;co&lt;/code&gt; for &lt;code&gt;checkout&lt;/code&gt;, &lt;code&gt;br&lt;/code&gt; for &lt;code&gt;branch&lt;/code&gt;, &lt;code&gt;ci&lt;/code&gt; for &lt;code&gt;commit&lt;/code&gt;, and &lt;code&gt;lg&lt;/code&gt; for a custom pretty log.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.lg &lt;span class="s2"&gt;"log --oneline --graph --all --decorate"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Staging &amp;amp; Committing
&lt;/h2&gt;

&lt;p&gt;The core workflow: make changes, stage them, commit them. Master these commands to keep your history clean and meaningful.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show working tree status — modified, staged, and untracked files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git add &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stage a specific file for commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stage all changes in current directory (new, modified, deleted)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git add -p&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stage changes interactively — choose which hunks to stage (patches)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit -m "message"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Commit staged changes with an inline message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit -am "message"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stage all tracked files and commit in one step (skips &lt;code&gt;git add&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit --amend&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Amend the last commit with new changes or a new message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git restore &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Discard uncommitted changes in a working file (modern alternative to checkout)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git restore --staged &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unstage a file but keep the changes in working directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git rm &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove a file from both working tree and staging area&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git mv &amp;lt;old&amp;gt; &amp;lt;new&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rename or move a file and stage the change&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Interactive Staging&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git add -p&lt;/code&gt; lets you stage parts of a file. This is invaluable for separating refactoring from feature work in a single file. Press &lt;strong&gt;y&lt;/strong&gt; to stage a hunk, &lt;strong&gt;n&lt;/strong&gt; to skip, &lt;strong&gt;s&lt;/strong&gt; to split, &lt;strong&gt;e&lt;/strong&gt; to manually edit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. Branching
&lt;/h2&gt;

&lt;p&gt;Branches are Git's superpower. Create, switch, list, and manage branches efficiently.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List local branches. Current branch highlighted with *&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all branches — local and remote tracking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a new branch at current HEAD (does not switch to it)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git checkout &amp;lt;branch&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Switch to an existing branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git checkout -b &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create and switch to a new branch in one step&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git switch &amp;lt;branch&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Modern alternative to checkout — switch branches cleanly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git switch -c &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create and switch to a new branch (modern &lt;code&gt;-b&lt;/code&gt; equivalent)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -d &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delete a branch (only if fully merged)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -D &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Force delete a branch even if not merged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git branch -m &amp;lt;old&amp;gt; &amp;lt;new&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rename a branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git show-branch&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show branches and their commits with ASCII graph&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  4. Remote Repositories
&lt;/h2&gt;

&lt;p&gt;Working with remotes — GitHub, GitLab, Bitbucket, or your own server. Push, pull, fetch, and manage remote connections.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git remote -v&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List remote repositories with fetch/push URLs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git remote add origin &amp;lt;url&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add a new remote named "origin"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git remote remove &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove a remote connection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git remote rename &amp;lt;old&amp;gt; &amp;lt;new&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Rename a remote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git fetch &amp;lt;remote&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Download objects and refs from remote without merging&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fetch from remote and merge into current branch (shortcut)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git pull --rebase&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fetch and rebase instead of merge (cleaner history)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Push commits to the remote tracking branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push -u origin &amp;lt;branch&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Push a new branch and set up tracking (&lt;code&gt;-u&lt;/code&gt; = &lt;code&gt;--set-upstream&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push --force&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Force push (use with extreme caution — prefer &lt;code&gt;--force-with-lease&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push --force-with-lease&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Safer force push — refuses if remote has new commits you haven't seen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push -d origin &amp;lt;branch&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delete a remote branch&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Force Push Safety&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Always use &lt;code&gt;--force-with-lease&lt;/code&gt; instead of &lt;code&gt;--force&lt;/code&gt;. It checks that the remote branch is in the state you expect before overwriting. Plain &lt;code&gt;--force&lt;/code&gt; can silently destroy a collaborator's work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  5. Undoing &amp;amp; Amending
&lt;/h2&gt;

&lt;p&gt;Everyone makes mistakes. Here's how to undo them safely at every stage.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git restore &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Discard unstaged changes in working directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git restore --staged &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unstage a file (keep working changes)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git reset HEAD~1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Undo last commit, keep changes staged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git reset --soft HEAD~1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Undo last commit, keep changes staged (same as above)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git reset --mixed HEAD~1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Undo last commit, keep changes unstaged (default behavior)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git reset --hard HEAD~1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Undo last commit and discard all changes completely&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git revert &amp;lt;commit&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a new commit that undoes a specific commit (safe for shared history)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git revert HEAD&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Undo the most recent commit with a new inverse commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit --amend -m "new msg"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Change the message of the last commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit --amend --no-edit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add staged changes to last commit without changing message&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Reset vs Revert&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reset&lt;/strong&gt; rewrites history — use only on local commits that haven't been pushed. &lt;strong&gt;Revert&lt;/strong&gt; creates a new commit that undoes the old one — safe for commits already pushed to shared branches.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  6. Merging
&lt;/h2&gt;

&lt;p&gt;Combine work from different branches. Understand merge vs rebase, and how to resolve conflicts.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git merge &amp;lt;branch&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Merge the specified branch into the current branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git merge --no-ff &amp;lt;branch&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Merge with a merge commit even if fast-forward is possible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git merge --squash &amp;lt;branch&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Merge all commits from branch into one single commit (no merge history)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git rebase &amp;lt;branch&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reapply current commits on top of another branch (linear history)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git rebase -i HEAD~3&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Interactive rebase: squash, reword, reorder, drop commits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git cherry-pick &amp;lt;commit&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apply a specific commit from another branch onto current branch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git mergetool&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Launch the configured merge tool to resolve conflicts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git merge --abort&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Abort current merge and restore pre-merge state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git rebase --abort&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Abort current rebase and restore pre-rebase state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git rebase --continue&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Continue rebase after resolving conflicts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Interactive rebase&lt;/strong&gt; is one of Git's most powerful features. Use it to clean up commits before merging:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Squash last 3 commits into one&lt;/span&gt;
git rebase -i HEAD~3

&lt;span class="c"&gt;# Available actions in the editor:&lt;/span&gt;
&lt;span class="c"&gt;# pick   - use commit as-is&lt;/span&gt;
&lt;span class="c"&gt;# reword - use commit but edit message&lt;/span&gt;
&lt;span class="c"&gt;# squash - combine with previous commit&lt;/span&gt;
&lt;span class="c"&gt;# fixup  - like squash but discard message&lt;/span&gt;
&lt;span class="c"&gt;# drop   - remove commit entirely&lt;/span&gt;
&lt;span class="c"&gt;# edit   - stop to amend the commit&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. Stashing
&lt;/h2&gt;

&lt;p&gt;Temporarily save uncommitted work when you need to switch branches or pull in changes. Your changes are saved in a stack and can be reapplied later.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stash all uncommitted changes (tracked files only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash push -m "message"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stash with a descriptive message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash -u&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stash including untracked files (&lt;code&gt;--include-untracked&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash -a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Stash all files including ignored ones (&lt;code&gt;--all&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash list&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;List all stashes in the stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash pop&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apply the most recent stash and remove it from the stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash apply&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apply the most recent stash but keep it in the stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash apply stash@{2}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apply a specific stash by index&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash drop stash@{n}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove a specific stash without applying it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash clear&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove all stashes (irreversible)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash show -p&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show the diff of the most recent stash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git stash branch &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a new branch from a stash and drop the stash&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  8. Logs &amp;amp; History
&lt;/h2&gt;

&lt;p&gt;Explore commit history, find changes, track down bugs, and understand who changed what and when.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show commit log with author, date, and message&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --oneline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Compact log — one line per commit (hash + message)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --graph --oneline --all&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ASCII graph of branch structure with compact log&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --oneline -n 5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show only the last 5 commits&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --author="name"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Filter commits by author&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --grep="pattern"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Search commit messages for a pattern&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log -p&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show full diff with each commit (very verbose)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --stat&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show commit metadata plus summary of changed files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show unstaged changes in working tree&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff --staged&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show staged changes (what will be committed)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git diff A..B&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show changes between two commits or branches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git show &amp;lt;commit&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show a specific commit with its diff&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git blame &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show who last modified each line of a file and when&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git shortlog -sn&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Summary of commits per author, sorted by count&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A useful alias for a beautiful, compact log view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log --graph --pretty=format:&lt;span class="s1"&gt;'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)&amp;lt;%an&amp;gt;%Creset'&lt;/span&gt; --all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;🎯 &lt;strong&gt;Quick Reference Card&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git clone &amp;lt;url&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git config --global user.name&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Daily&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git add -p&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git commit -m&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Branches&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git switch -c &amp;lt;name&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git merge &amp;lt;branch&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git rebase -i HEAD~3&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Fix Mistakes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git restore &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git commit --amend&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git revert HEAD&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git stash&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Common Mistakes &amp;amp; How to Avoid Them
&lt;/h2&gt;

&lt;p&gt;These are the mistakes I see most often in pull requests and on incident calls — and the exact commands to recover from them before they cost you an afternoon.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Committing secrets to the repository.&lt;/strong&gt; A stray &lt;code&gt;.env&lt;/code&gt; file or API key in a commit is the most expensive mistake in git. Rotate the credential immediately, then scrub history with &lt;code&gt;git filter-repo --path .env --invert-paths&lt;/code&gt;. Deleting the file and committing again is not enough — the secret stays in history.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trusting &lt;code&gt;git commit -am&lt;/code&gt; to catch everything.&lt;/strong&gt; The &lt;code&gt;-a&lt;/code&gt; flag only stages changes to already tracked files; brand-new files are silently skipped. That's how "forgot to add file" commits happen. Run &lt;code&gt;git status&lt;/code&gt; before committing and review hunks with &lt;code&gt;git add -p&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Force-pushing to shared branches.&lt;/strong&gt; A bare &lt;code&gt;git push --force&lt;/code&gt; rewrites history and can destroy your teammates' commits. Use &lt;code&gt;git push --force-with-lease&lt;/code&gt; instead — it aborts if the remote contains commits you haven't seen.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Amending commits that were already pushed.&lt;/strong&gt; &lt;code&gt;git commit --amend&lt;/code&gt; is a local operation. Amending a pushed commit creates divergent history and a confusing merge on the next pull. If the commit is on the remote, use &lt;code&gt;git revert &amp;lt;sha&amp;gt;&lt;/code&gt; to add a new commit that undoes it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deleting both sides of a merge conflict.&lt;/strong&gt; Stripping everything between the &lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; markers often discards both versions. Read both sides, decide what to keep, then verify with &lt;code&gt;git diff --check&lt;/code&gt; that no conflict markers remain before staging.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How do I undo the last commit but keep my changes?
&lt;/h3&gt;

&lt;p&gt;Run &lt;code&gt;git reset --soft HEAD~1&lt;/code&gt; to undo the commit while keeping your changes staged, or &lt;code&gt;git reset HEAD~1&lt;/code&gt; to unstage them. If the commit was already pushed, don't rewrite history — use &lt;code&gt;git revert HEAD&lt;/code&gt; to add a new commit that undoes it. For a simple message fix, &lt;code&gt;git commit --amend&lt;/code&gt; is enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I resolve merge conflicts?
&lt;/h3&gt;

&lt;p&gt;Run &lt;code&gt;git status&lt;/code&gt; to list conflicted files. Open each one, remove the &lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/code&gt;, &lt;code&gt;=======&lt;/code&gt;, and &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; markers, and keep the version(s) you want. Stage with &lt;code&gt;git add&lt;/code&gt;, then finish with &lt;code&gt;git commit&lt;/code&gt;. To bail out entirely, run &lt;code&gt;git merge --abort&lt;/code&gt;. To take one side wholesale: &lt;code&gt;git checkout --ours &amp;lt;file&amp;gt;&lt;/code&gt; or &lt;code&gt;git checkout --theirs &amp;lt;file&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the difference between git fetch and git pull?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;git fetch&lt;/code&gt; downloads new commits into remote-tracking branches (like &lt;code&gt;origin/main&lt;/code&gt;) without touching your working tree. &lt;code&gt;git pull&lt;/code&gt; is fetch followed by a merge — or a rebase with &lt;code&gt;git pull --rebase&lt;/code&gt;. Fetch when you want to inspect changes first; pull when you're ready to integrate them into your branch.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I recover a deleted branch or lost commits?
&lt;/h3&gt;

&lt;p&gt;Run &lt;code&gt;git reflog&lt;/code&gt; to see every HEAD movement, find the SHA of the commit you lost, then recreate the branch with &lt;code&gt;git branch &amp;lt;name&amp;gt; &amp;lt;sha&amp;gt;&lt;/code&gt; or check it out directly. Reflog entries expire after about 90 days (default), so act quickly before garbage collection removes them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does git keep asking me for my password?
&lt;/h3&gt;

&lt;p&gt;You're using HTTPS without a credential helper. Set one with &lt;code&gt;git config --global credential.helper store&lt;/code&gt; (or &lt;code&gt;cache&lt;/code&gt; for temporary caching), or switch to SSH keys generated with &lt;code&gt;ssh-keygen&lt;/code&gt;. For HTTPS, GitHub and GitLab now require personal access tokens instead of account passwords.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Related Tools:&lt;/strong&gt; &lt;a href="https://devtoolshub.cloud/tools/regex-tester" rel="noopener noreferrer"&gt;Regex Tester&lt;/a&gt; · &lt;a href="https://devtoolshub.cloud/tools/base64" rel="noopener noreferrer"&gt;Base64 Encoder/Decoder&lt;/a&gt; · &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;JSON Formatter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you found this cheat sheet useful, bookmark &lt;a href="https://devtoolshub.cloud" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — it's a free, privacy-first toolkit for developers with no sign-ups and no tracking: regex testing, Base64 and JSON utilities, timestamp conversion, JWT decoding, UUID generation, and more. All tools run entirely in your browser.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>git</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>REST vs GraphQL: Which API Style Should You Use in 2026?</title>
      <dc:creator>kingfujing</dc:creator>
      <pubDate>Fri, 04 Sep 2026 11:29:50 +0000</pubDate>
      <link>https://dev.to/kingfujing/rest-vs-graphql-which-api-style-should-you-use-in-2026-4fgf</link>
      <guid>https://dev.to/kingfujing/rest-vs-graphql-which-api-style-should-you-use-in-2026-4fgf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://devtoolshub.cloud/blog/rest-vs-graphql" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — free, privacy-first developer tools that run entirely in your browser.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;REST and GraphQL are the two dominant ways to design a web API today, and the debate between them is still alive — for good reason. They embody different philosophies: &lt;strong&gt;REST organizes an API around resources and HTTP semantics&lt;/strong&gt;, while &lt;strong&gt;GraphQL organizes it around a typed schema and client-specified queries&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this guide, we'll compare them across data fetching, caching, versioning, and real-world performance — so you can pick the right style for your next project instead of just following the hype.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Quick Try:&lt;/strong&gt; Both styles return JSON. Paste any API response into the free &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;DevToolsHub JSON Formatter&lt;/a&gt; to inspect it with syntax highlighting and validation.&lt;/p&gt;

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

&lt;p&gt;REST (Representational State Transfer) is an &lt;strong&gt;architectural style&lt;/strong&gt; formalized by Roy Fielding in 2000. A RESTful API exposes &lt;strong&gt;resources&lt;/strong&gt; as URLs, manipulates them with &lt;strong&gt;HTTP verbs&lt;/strong&gt; (GET, POST, PUT, DELETE), and communicates outcomes through &lt;strong&gt;status codes&lt;/strong&gt; (200, 201, 404, 429...). There is no single spec to implement — HTTP itself is the protocol, and conventions do the rest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET    /users/42          → 200 OK (one user)
GET    /users/42/posts    → 200 OK (their posts)
POST   /users             → 201 Created
DELETE /users/42          → 204 No Content
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Simple and universally understood. HTTP caching (ETags, Cache-Control, CDNs) works out of the box. Status codes carry meaning. Any client, from curl to a smart fridge, can consume it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Clients often need multiple round trips to assemble one view (&lt;em&gt;under-fetching&lt;/em&gt;) or receive more data than they need (&lt;em&gt;over-fetching&lt;/em&gt;). Endpoint sprawl grows with every new screen, and versioning (v1, v2...) becomes a maintenance burden.&lt;/p&gt;

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

&lt;p&gt;GraphQL is a &lt;strong&gt;query language for APIs and a runtime for executing those queries&lt;/strong&gt;, open-sourced by Facebook in 2015 and now governed by the GraphQL Foundation. Instead of many endpoints, there is &lt;strong&gt;one endpoint and one strongly-typed schema&lt;/strong&gt;. The client asks for exactly the fields it needs — in the exact shape it wants — and the server resolves them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight graphql"&gt;&lt;code&gt;&lt;span class="c"&gt;# One request: user + their posts, precisely shaped&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="k"&gt;query&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="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;42&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="n"&gt;name&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&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="n"&gt;title&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="n"&gt;commentsCount&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; No over-fetching — the response mirrors the query. One round trip for nested data. A self-documenting type system with introspection (GraphiQL, generated SDKs). Frontend teams ship features without waiting for new endpoints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; HTTP-level caching largely disappears (everything is a POST to one URL). Resolver complexity can hide N+1 database queries. Query depth and cost must be limited to prevent abuse. More server-side machinery and a real learning curve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Head-to-Head Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;REST&lt;/th&gt;
&lt;th&gt;GraphQL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Type&lt;/td&gt;
&lt;td&gt;✅ Architectural style&lt;/td&gt;
&lt;td&gt;✅ Query language + runtime&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Endpoints&lt;/td&gt;
&lt;td&gt;Many (per resource)&lt;/td&gt;
&lt;td&gt;One&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data shape&lt;/td&gt;
&lt;td&gt;⚠️ Fixed by server&lt;/td&gt;
&lt;td&gt;✅ Chosen by client&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Over-fetching&lt;/td&gt;
&lt;td&gt;❌ Common&lt;/td&gt;
&lt;td&gt;✅ Eliminated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP caching / CDN&lt;/td&gt;
&lt;td&gt;✅ Native&lt;/td&gt;
&lt;td&gt;❌ Needs custom layers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Versioning&lt;/td&gt;
&lt;td&gt;⚠️ URL/header versions&lt;/td&gt;
&lt;td&gt;✅ Schema evolution + deprecation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learning curve&lt;/td&gt;
&lt;td&gt;✅ Low&lt;/td&gt;
&lt;td&gt;❌ Moderate to high&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Real Story: Trade-offs in Production
&lt;/h2&gt;

&lt;p&gt;GraphQL was born from a concrete pain: Facebook's mobile news feed needed a deeply nested view of stories, authors, likes, and comments. With REST, that meant either a bespoke aggregation endpoint per screen or a waterfall of small requests over slow mobile networks. GraphQL flipped the contract — &lt;strong&gt;the client declares the view, the server composes it&lt;/strong&gt;. For product teams iterating on UI weekly, that flexibility is the real selling point, not the absence of over-fetching alone.&lt;/p&gt;

&lt;p&gt;But the costs are equally concrete. Because GraphQL requests are typically POSTs to a single URL, &lt;strong&gt;you lose HTTP caching almost entirely&lt;/strong&gt; — no more free CDN caching of GET responses; caching moves into client libraries (Apollo, Relay) and custom server layers. And the resolver model introduces the classic &lt;strong&gt;N+1 problem&lt;/strong&gt;: a list of 50 users can trigger 50 separate database lookups unless you batch with a tool like &lt;code&gt;DataLoader&lt;/code&gt;. REST avoids this by design because each endpoint is a single handler you profile once.&lt;/p&gt;

&lt;p&gt;The mature take in 2026: &lt;strong&gt;most serious platforms run both&lt;/strong&gt; — REST for public, cache-heavy, resource-shaped APIs; GraphQL as an internal BFF (backend-for-frontend) layer where the client shape flexibility pays off.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use Each
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use REST when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You're building a &lt;strong&gt;public API&lt;/strong&gt; for third-party developers&lt;/li&gt;
&lt;li&gt;Responses are &lt;strong&gt;cacheable&lt;/strong&gt; and CDN/HTTP caching matters&lt;/li&gt;
&lt;li&gt;The domain is &lt;strong&gt;resource-shaped&lt;/strong&gt; (CRUD on clear entities)&lt;/li&gt;
&lt;li&gt;You need &lt;strong&gt;file uploads/downloads&lt;/strong&gt; or streaming&lt;/li&gt;
&lt;li&gt;The team wants &lt;strong&gt;standard tooling&lt;/strong&gt; and a low learning curve&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use GraphQL when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Clients are &lt;strong&gt;mobile or bandwidth-sensitive&lt;/strong&gt; and over-fetching hurts&lt;/li&gt;
&lt;li&gt;Screens need &lt;strong&gt;nested, aggregated data&lt;/strong&gt; from many services&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;frontend iterates fast&lt;/strong&gt; and endpoint sprawl is slowing you down&lt;/li&gt;
&lt;li&gt;You're unifying microservices behind a &lt;strong&gt;graph/federation layer&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Multiple clients need &lt;strong&gt;different views of the same data&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Node.js / Express: A REST endpoint
&lt;/h3&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;express&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;express&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/users/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&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="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;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User not found&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Cache-Control&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;public, max-age=60&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// HTTP caching, free&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Apollo Server: The same data as GraphQL
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ApolloServer&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;@apollo/server&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;startStandaloneServer&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;@apollo/server/standalone&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;typeDefs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
  type Post { title: String! }
  type User { name: String! posts: [Post!]! }
  type Query { user(id: ID!): User }
`&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;resolvers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&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;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="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByUserId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="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;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ApolloServer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;typeDefs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;resolvers&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;startStandaloneServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4000&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;Notice the difference: REST returns one fixed shape per URL; GraphQL lets the client compose &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;posts&lt;/code&gt; in one request — at the price of managing a schema and resolvers on the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Verdict
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;🎯 &lt;strong&gt;Recommendation:&lt;/strong&gt; Neither one "wins" — &lt;strong&gt;they solve different problems&lt;/strong&gt;. Choose &lt;strong&gt;REST&lt;/strong&gt; when your API is resource-shaped, benefits from HTTP caching, or is consumed by third parties. Choose &lt;strong&gt;GraphQL&lt;/strong&gt; when client flexibility, nested views, and rapid frontend iteration are worth the extra server complexity. For most growing products: &lt;strong&gt;REST for the public edge, GraphQL as the internal BFF&lt;/strong&gt; — the pragmatic hybrid.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Working with either style, you'll live in JSON responses — &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;format and validate them in your browser&lt;/a&gt; with the free DevToolsHub JSON Formatter, no uploads required.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes &amp;amp; How to Avoid Them
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Using GraphQL as a database.&lt;/strong&gt; It's an API layer, not a query engine. Resolvers still execute database queries — a naive schema can generate worse queries than a hand-written REST handler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring the N+1 problem.&lt;/strong&gt; A list resolver that runs one query per item will melt your database under load. Batch with &lt;code&gt;DataLoader&lt;/code&gt; or equivalent from day one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shipping GraphQL without depth limits.&lt;/strong&gt; A malicious client can ask for infinitely nested queries and take your server down. Add depth limiting, cost analysis, or persisted queries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versioning GraphQL like REST.&lt;/strong&gt; There is no v2 in GraphQL — evolve the schema: add fields, mark old ones &lt;code&gt;@deprecated&lt;/code&gt;, and remove them only after usage monitoring shows they're gone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caching REST at the wrong level.&lt;/strong&gt; If your REST responses vary by auth token, don't mark them publicly cacheable — you'll leak one user's data to another. Cache public resources; use ETags for the rest.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is GraphQL replacing REST?
&lt;/h3&gt;

&lt;p&gt;No. REST remains the default for public APIs, simple resource operations, and anything that benefits from HTTP caching. GraphQL thrives in specific niches: mobile clients, aggregated views, and fast-moving frontend teams. Most large platforms run both.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is GraphQL faster than REST?
&lt;/h3&gt;

&lt;p&gt;It depends. GraphQL saves round trips for nested data (fewer network hops), but adds resolver overhead and loses HTTP caching. For a simple, cacheable resource, a well-designed REST endpoint served from a CDN is often faster end to end.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use REST and GraphQL together?
&lt;/h3&gt;

&lt;p&gt;Yes — and it's the most common architecture at scale. Expose a public REST API, and run an internal GraphQL BFF (backend-for-frontend) that aggregates your services for the app teams.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does GraphQL only work over HTTP POST?
&lt;/h3&gt;

&lt;p&gt;Queries and mutations are typically sent as HTTP POST to a single endpoint (GET is possible for queries but rare). Subscriptions use WebSocket or Server-Sent Events instead of plain HTTP.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does caching work in GraphQL?
&lt;/h3&gt;

&lt;p&gt;HTTP caching doesn't apply naturally because everything is a POST. Caching moves to normalized client-side stores (Apollo Client, Relay) and custom server layers like response caching or APQ (Automatic Persisted Queries).&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Related Tools:&lt;/strong&gt; &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;JSON Formatter&lt;/a&gt; · &lt;a href="https://devtoolshub.cloud/tools/url-encoder" rel="noopener noreferrer"&gt;URL Encoder / Decoder&lt;/a&gt; · &lt;a href="https://devtoolshub.cloud/tools/jwt-decoder" rel="noopener noreferrer"&gt;JWT Decoder&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you found this useful, check out &lt;a href="https://devtoolshub.cloud" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — 9 free privacy-first developer tools, everything runs locally in your browser.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>api</category>
      <category>graphql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>JWT vs OAuth2: What's the Difference and When to Use Each?</title>
      <dc:creator>kingfujing</dc:creator>
      <pubDate>Tue, 25 Aug 2026 11:39:26 +0000</pubDate>
      <link>https://dev.to/kingfujing/jwt-vs-oauth2-whats-the-difference-and-when-to-use-each-50ic</link>
      <guid>https://dev.to/kingfujing/jwt-vs-oauth2-whats-the-difference-and-when-to-use-each-50ic</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://devtoolshub.cloud" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — free, privacy-first online tools for developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;JWT and OAuth2 are two of the most confused terms in modern web development. Many developers treat them as interchangeable — but they solve completely different problems. &lt;strong&gt;JWT is a token format&lt;/strong&gt;, while &lt;strong&gt;OAuth2 is an authorization framework&lt;/strong&gt;. They often work together, which is exactly why the confusion exists.&lt;/p&gt;

&lt;p&gt;In this guide, we'll compare JWT and OAuth2 across their roles, use cases, and how they combine — so you know what you're actually implementing in your next project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Quick Try:&lt;/strong&gt; Have a token to inspect? Use our free &lt;a href="https://devtoolshub.cloud/tools/jwt-decoder" rel="noopener noreferrer"&gt;JWT Decoder&lt;/a&gt; to decode and verify tokens right in your browser.&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;p&gt;JWT (JSON Web Token) is a &lt;strong&gt;compact, self-contained token format&lt;/strong&gt; defined by RFC 7519. It's a JSON object encoded as a string, containing claims like user ID, role, and expiry, signed with a secret or public key. Anyone with the signing key can verify the token's authenticity without contacting a server.&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="err"&gt;header.payload.signature&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;header:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"HS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"typ"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"JWT"&lt;/span&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;payload:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"admin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;1700000000&lt;/span&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;signature:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HMACSHA&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="err"&gt;(base&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="err"&gt;Url(header)+&lt;/span&gt;&lt;span class="s2"&gt;"."&lt;/span&gt;&lt;span class="err"&gt;+base&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="err"&gt;Url(payload),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;secret)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Self-contained — carries claims without a lookup. Verifiable offline. Works across any service that shares the key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Just a token format — doesn't define &lt;em&gt;how&lt;/em&gt; to get, refresh, or revoke it. No built-in scopes or third-party flow.&lt;/p&gt;

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

&lt;p&gt;OAuth2 is an &lt;strong&gt;authorization framework&lt;/strong&gt; (RFC 6749) that defines how a user can grant a third-party application limited access to their resources. It involves &lt;strong&gt;roles&lt;/strong&gt; (resource owner, client, authorization server, resource server), &lt;strong&gt;flows&lt;/strong&gt; (authorization code, client credentials, PKCE), and &lt;strong&gt;scopes&lt;/strong&gt; that limit what the token can do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OAuth2 roles:
┌─────────────┐      ┌──────────────────┐
│  User (RO)  │      │ Client (App)     │
└──────┬──────┘      └────────┬─────────┘
       │                      │
       ▼                      ▼
┌─────────────────────────────────────┐
│  Authorization Server (e.g. Google) │
│  Issues access tokens + scopes      │
└─────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Standardized flows for third-party login. Scopes limit permissions. Industry standard for "Sign in with Google/GitHub".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Complex — multiple flows, redirects, and endpoints to manage. Tokens themselves can be any format (often JWT, but not required).&lt;/p&gt;

&lt;h2&gt;
  
  
  Head-to-Head Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;JWT&lt;/th&gt;
&lt;th&gt;OAuth2&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Type&lt;/td&gt;
&lt;td&gt;✅ Token format&lt;/td&gt;
&lt;td&gt;✅ Authorization framework&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Solves&lt;/td&gt;
&lt;td&gt;How to encode claims&lt;/td&gt;
&lt;td&gt;How to grant access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication&lt;/td&gt;
&lt;td&gt;✅ Can carry auth data&lt;/td&gt;
&lt;td&gt;❌ Authorization only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scopes&lt;/td&gt;
&lt;td&gt;❌ Not built-in&lt;/td&gt;
&lt;td&gt;✅ First-class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Third-party login&lt;/td&gt;
&lt;td&gt;❌ Not defined&lt;/td&gt;
&lt;td&gt;✅ Core use case&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Refresh flow&lt;/td&gt;
&lt;td&gt;❌ Your job&lt;/td&gt;
&lt;td&gt;✅ Standardized&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Token format&lt;/td&gt;
&lt;td&gt;✅ JWT (always)&lt;/td&gt;
&lt;td&gt;⚠️ Opaque or JWT&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  How They Work Together: The Real Story
&lt;/h2&gt;

&lt;p&gt;The confusion comes from the fact that &lt;strong&gt;OAuth2 often uses JWT as its access token format&lt;/strong&gt;. When you sign in with Google, Google's authorization server issues an access token — and that token is frequently a JWT. So you're using both: &lt;strong&gt;OAuth2 for the flow, JWT for the token&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A common implementation: OAuth2 Authorization Code flow with PKCE obtains a JWT access token. The resource server verifies the JWT signature offline (no database lookup), while the authorization server handles issuing, refreshing, and revoking through OAuth2 endpoints.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JWT alone&lt;/strong&gt; — fine for first-party apps (your SPA talking to your API)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OAuth2 alone&lt;/strong&gt; — possible with opaque tokens (server validates via introspection)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OAuth2 + JWT&lt;/strong&gt; — the industry standard for third-party access&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to Use Each
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use JWT when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You need a &lt;strong&gt;self-contained, verifiable token&lt;/strong&gt; for your own API&lt;/li&gt;
&lt;li&gt;You want &lt;strong&gt;stateless auth&lt;/strong&gt; across microservices sharing a key&lt;/li&gt;
&lt;li&gt;You're building a &lt;strong&gt;first-party SPA/mobile app&lt;/strong&gt; with your own login&lt;/li&gt;
&lt;li&gt;You need to embed claims (role, permissions) in the token itself&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use OAuth2 when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You need &lt;strong&gt;"Sign in with Google/GitHub/Facebook"&lt;/strong&gt; third-party login&lt;/li&gt;
&lt;li&gt;A third-party app needs &lt;strong&gt;limited access&lt;/strong&gt; to your users' resources&lt;/li&gt;
&lt;li&gt;You need &lt;strong&gt;scopes&lt;/strong&gt; to control what each token can do&lt;/li&gt;
&lt;li&gt;You're building an &lt;strong&gt;API platform&lt;/strong&gt; that other developers integrate&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Node.js: Sign-in with Google (OAuth2 + JWT)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;OAuth2Client&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;google-auth-library&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;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsonwebtoken&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;OAuth2Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GOOGLE_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Frontend sends the Google ID token after OAuth2 flow&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;googleLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;idToken&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// 1. Verify the Google-issued token (OAuth2 flow result)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ticket&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verifyIdToken&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;idToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;audience&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GOOGLE_CLIENT_ID&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;email&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;=&lt;/span&gt; &lt;span class="nx"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPayload&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// 2. Issue your own JWT for your API&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appToken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;email&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="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1h&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;appToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Python / FastAPI: JWT-only auth (first-party)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTTPException&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi.security&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OAuth2PasswordBearer&lt;/span&gt;

&lt;span class="c1"&gt;# OAuth2PasswordBearer is just a token extractor — the token itself is a JWT
&lt;/span&gt;&lt;span class="n"&gt;oauth2_scheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OAuth2PasswordBearer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokenUrl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/login&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_current_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oauth2_scheme&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;algorithms&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HS256&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sub&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PyJWTError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Verdict
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;🎯 &lt;strong&gt;Recommendation:&lt;/strong&gt; They're not competitors — &lt;strong&gt;they're complementary&lt;/strong&gt;. Use &lt;strong&gt;OAuth2&lt;/strong&gt; when you need standardized third-party login or scoped access to resources. Use &lt;strong&gt;JWT&lt;/strong&gt; as the token format for fast, stateless verification. For most production apps: &lt;strong&gt;OAuth2 for the flow, JWT for the token&lt;/strong&gt; — best of both worlds.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Decode and inspect any JWT instantly with our free &lt;a href="https://devtoolshub.cloud/tools/jwt-decoder" rel="noopener noreferrer"&gt;online JWT Decoder&lt;/a&gt;. It runs entirely in your browser — no server uploads, no data leaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes &amp;amp; How to Avoid Them
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Calling OAuth2 an authentication protocol.&lt;/strong&gt; OAuth2 is about &lt;em&gt;authorization&lt;/em&gt; (what you can access). For identity, pair it with OIDC (OpenID Connect) which adds an ID token.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assuming OAuth2 requires JWT.&lt;/strong&gt; OAuth2 tokens can be opaque strings validated via server introspection. JWT is optional — though very common.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using JWT for third-party login.&lt;/strong&gt; JWT alone has no flow for redirecting users to Google. You need OAuth2 (or OIDC) for the dance, JWT for the ticket.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring scopes.&lt;/strong&gt; If you hand out full-access tokens, you've missed the point of OAuth2. Always request the minimum scopes needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reinventing the wheel.&lt;/strong&gt; Don't build your own OAuth2 server unless you must. Use Auth0, Keycloak, or the identity provider's managed flow.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is JWT the same as OAuth2?
&lt;/h3&gt;

&lt;p&gt;No. JWT is a token format (how claims are encoded), while OAuth2 is an authorization framework (how access is granted). OAuth2 commonly uses JWT as its token format, but they are distinct concepts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does OAuth2 use JWT tokens?
&lt;/h3&gt;

&lt;p&gt;Often yes, but not required. Many identity providers (Google, Auth0) issue JWT access tokens, but OAuth2 also supports opaque tokens validated via the introspection endpoint. JWT is the popular choice for stateless verification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I use JWT or OAuth2 for my app?
&lt;/h3&gt;

&lt;p&gt;For a first-party app with your own login, JWT alone is usually enough. For third-party login (Sign in with Google/GitHub) or building an API for other developers, use OAuth2 — with JWT as the token format.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between OAuth2 and OIDC?
&lt;/h3&gt;

&lt;p&gt;OAuth2 handles authorization (access tokens, scopes). OIDC (OpenID Connect) builds on OAuth2 and adds an ID token for authentication — so you know &lt;em&gt;who&lt;/em&gt; the user is, not just what they can access.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use JWT without OAuth2?
&lt;/h3&gt;

&lt;p&gt;Absolutely. JWT is a standalone standard. You can issue and verify JWTs with your own login endpoint, no OAuth2 involved. OAuth2 only becomes necessary when you need third-party flows or scoped delegation.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>security</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>SQL vs NoSQL: Which Database Should You Choose in 2026?</title>
      <dc:creator>kingfujing</dc:creator>
      <pubDate>Tue, 25 Aug 2026 11:39:20 +0000</pubDate>
      <link>https://dev.to/kingfujing/sql-vs-nosql-which-database-should-you-choose-in-2026-1o00</link>
      <guid>https://dev.to/kingfujing/sql-vs-nosql-which-database-should-you-choose-in-2026-1o00</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://devtoolshub.cloud" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — free, privacy-first online tools for developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Choosing a database is one of the most consequential decisions in software architecture. &lt;strong&gt;SQL&lt;/strong&gt; (PostgreSQL, MySQL) has ruled for 40+ years with rock-solid transactions. &lt;strong&gt;NoSQL&lt;/strong&gt; (MongoDB, Redis, Cassandra) powers modern web scale with flexible schemas. But "SQL vs NoSQL" is not a one-size-fits-all battle — the right answer depends on your data, your scale, and your consistency requirements.&lt;/p&gt;

&lt;p&gt;In this guide, we'll compare SQL and NoSQL across schema flexibility, scalability, transactions, and query power — so you can make an informed choice for your next project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Quick Try:&lt;/strong&gt; Working with JSON data from your database? Use our free &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;JSON Formatter&lt;/a&gt; to beautify and validate it right in your browser.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What is SQL (Relational)?
&lt;/h2&gt;

&lt;p&gt;SQL databases organize data into &lt;strong&gt;tables with fixed schemas&lt;/strong&gt; — rows and columns connected by relationships (foreign keys). They guarantee &lt;strong&gt;ACID transactions&lt;/strong&gt; (Atomicity, Consistency, Isolation, Durability), which makes them the default choice for anything involving money, orders, or critical business data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Fixed schema: every row has all columns&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Powerful joins across related tables&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'paid'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; ACID transactions. Mature ecosystem and tooling. Complex queries with JOINs. Enforced data integrity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Rigid schema — migrations are work. Vertical scaling is expensive. Sharding across nodes is complex.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is NoSQL (Non-Relational)?
&lt;/h2&gt;

&lt;p&gt;NoSQL is an umbrella term for databases that don't use the relational model. Common types: &lt;strong&gt;document&lt;/strong&gt; (MongoDB), &lt;strong&gt;key-value&lt;/strong&gt; (Redis), &lt;strong&gt;column-family&lt;/strong&gt; (Cassandra), and &lt;strong&gt;graph&lt;/strong&gt; (Neo4j). They trade strict consistency for &lt;strong&gt;flexibility and horizontal scalability&lt;/strong&gt; — schemas are flexible, and data scales across many cheap nodes.&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Document&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;store:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;schema-less,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;embed&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;related&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;data&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;"_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"507f1f77bcf86cd799439011"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alice@example.com"&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;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"orders"&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;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;99.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"paid"&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="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;related&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;embedded&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;no&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JOIN&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;needed&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Flexible schema — iterate fast. Horizontal scaling via sharding. Great for high write throughput and unstructured data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; No ACID guarantees (mostly). Complex queries require denormalization or aggregation pipelines. Consistency is often eventual.&lt;/p&gt;

&lt;h2&gt;
  
  
  Head-to-Head Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;SQL&lt;/th&gt;
&lt;th&gt;NoSQL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Schema&lt;/td&gt;
&lt;td&gt;✅ Fixed, enforced&lt;/td&gt;
&lt;td&gt;❌ Flexible, dynamic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transactions&lt;/td&gt;
&lt;td&gt;✅ ACID&lt;/td&gt;
&lt;td&gt;⚠️ Limited / eventual&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaling&lt;/td&gt;
&lt;td&gt;⚠️ Vertical (expensive)&lt;/td&gt;
&lt;td&gt;✅ Horizontal (sharding)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Queries&lt;/td&gt;
&lt;td&gt;✅ Powerful JOINs&lt;/td&gt;
&lt;td&gt;⚠️ Limited relations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flexibility&lt;/td&gt;
&lt;td&gt;❌ Migrations needed&lt;/td&gt;
&lt;td&gt;✅ Iterate instantly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maturity&lt;/td&gt;
&lt;td&gt;✅ 40+ years&lt;/td&gt;
&lt;td&gt;⚠️ 15+ years&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for&lt;/td&gt;
&lt;td&gt;Money, orders, integrity&lt;/td&gt;
&lt;td&gt;Scale, flexibility, speed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Scaling and Consistency: The Real Story
&lt;/h2&gt;

&lt;p&gt;The biggest divide is the &lt;strong&gt;CAP theorem&lt;/strong&gt;. SQL databases prioritize &lt;strong&gt;consistency&lt;/strong&gt; — every read sees the latest write. NoSQL databases often prioritize &lt;strong&gt;availability and partition tolerance&lt;/strong&gt;, accepting eventual consistency (reads may briefly see stale data).&lt;/p&gt;

&lt;p&gt;In practice: a banking ledger &lt;em&gt;must&lt;/em&gt; be consistent (SQL). A social media feed can tolerate a few seconds of staleness for the benefit of scaling to millions of users (NoSQL). Modern databases blur the line — &lt;strong&gt;PostgreSQL supports JSON columns&lt;/strong&gt; for flexibility, and &lt;strong&gt;MongoDB added multi-document transactions&lt;/strong&gt; — but the core tradeoff remains.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use Each
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use SQL when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Data has &lt;strong&gt;clear relationships&lt;/strong&gt; (users → orders → items)&lt;/li&gt;
&lt;li&gt;You need &lt;strong&gt;ACID transactions&lt;/strong&gt; (payments, inventory, bookings)&lt;/li&gt;
&lt;li&gt;You need &lt;strong&gt;complex queries&lt;/strong&gt; with JOINs and aggregations&lt;/li&gt;
&lt;li&gt;Data integrity is &lt;strong&gt;non-negotiable&lt;/strong&gt; (finance, healthcare)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use NoSQL when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You have &lt;strong&gt;unstructured or rapidly changing&lt;/strong&gt; data shapes&lt;/li&gt;
&lt;li&gt;You need to &lt;strong&gt;scale horizontally&lt;/strong&gt; to millions of users/writes&lt;/li&gt;
&lt;li&gt;You're building &lt;strong&gt;real-time, high-throughput&lt;/strong&gt; systems (caching, events)&lt;/li&gt;
&lt;li&gt;Your queries are &lt;strong&gt;simple lookups&lt;/strong&gt;, not complex joins&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  PostgreSQL: Relational with JSONB (hybrid)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Best of both: relational integrity + flexible JSON&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="nb"&gt;NUMERIC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="n"&gt;JSONB&lt;/span&gt;  &lt;span class="c1"&gt;-- flexible metadata&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Query inside JSON&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="s1"&gt;'color'&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'red'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  MongoDB: Document model
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Embedded documents avoid expensive joins&lt;/span&gt;
&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;insertOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ObjectId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;items&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="na"&gt;sku&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;qty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;29.99&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;sku&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;qty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;9.99&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;69.97&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Flexible query with aggregation pipeline&lt;/span&gt;
&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;aggregate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;paid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$group&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$userId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;$sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$total&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Redis: Key-value cache
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Lightning-fast reads for hot data
SET session:user:1001 "{ \"name\": \"Alice\", \"role\": \"admin\" }"
EXPIRE session:user:1001 3600

// Rate limiting with atomic increment
INCR rate:api:user-1001
EXPIRE rate:api:user-1001 60
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Verdict
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;🎯 &lt;strong&gt;Recommendation:&lt;/strong&gt; Start with &lt;strong&gt;SQL (PostgreSQL)&lt;/strong&gt; unless you have a specific reason not to. It handles 95% of applications with ACID guarantees and a mature ecosystem. Reach for &lt;strong&gt;NoSQL&lt;/strong&gt; when you hit real scale problems, need flexible schemas for unstructured data, or require high write throughput. Most production systems use &lt;strong&gt;both&lt;/strong&gt; — SQL for canonical data, NoSQL for caching and hot paths.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Format and validate JSON from your database queries with our free &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;online JSON Formatter&lt;/a&gt;. It runs entirely in your browser — no server uploads, no data leaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes &amp;amp; How to Avoid Them
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Choosing NoSQL for the wrong reason.&lt;/strong&gt; "MongoDB is trendy" is not a requirement. If you need JOINs and transactions, SQL will save you months of pain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring schema migrations in SQL.&lt;/strong&gt; Every schema change is work. Plan migrations with tools like Prisma or Flyway from day one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assuming NoSQL means no constraints.&lt;/strong&gt; Flexible schema still needs validation — enforce it in your application layer or schema validation features (MongoDB validation rules).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storing everything in one database.&lt;/strong&gt; Use the right tool for each job: PostgreSQL for canonical data, Redis for cache, Elasticsearch for search.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring the CAP tradeoff.&lt;/strong&gt; If your NoSQL system promises strong consistency, you're paying for it elsewhere — usually in availability or latency. Know your tradeoff.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is NoSQL faster than SQL?
&lt;/h3&gt;

&lt;p&gt;Not inherently. NoSQL is often faster for simple lookups and high write throughput because it avoids JOINs and scales horizontally. But SQL with proper indexes is extremely fast too. The speed difference comes from workload design, not the database category.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use SQL and NoSQL together?
&lt;/h3&gt;

&lt;p&gt;Yes, this is a polyglot persistence pattern. Use SQL for canonical data with ACID guarantees, Redis for caching, and Elasticsearch for full-text search. Many production systems combine multiple databases per concern.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is MongoDB better than PostgreSQL?
&lt;/h3&gt;

&lt;p&gt;Neither is universally better. PostgreSQL wins for relational data, complex queries, and transactions. MongoDB wins for flexible schemas and horizontal scaling. Modern PostgreSQL even supports JSONB, closing much of the gap.&lt;/p&gt;

&lt;h3&gt;
  
  
  When should I switch from SQL to NoSQL?
&lt;/h3&gt;

&lt;p&gt;Only switch when you hit concrete problems SQL can't solve: horizontal write scaling beyond a single node, unstructured data with rapidly evolving shapes, or very high throughput requirements. "We might need it someday" is not a good reason.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the best database for a new startup?
&lt;/h3&gt;

&lt;p&gt;PostgreSQL. It's free, battle-tested, handles JSON (JSONB) for flexibility, scales to millions of rows, and won't become a bottleneck as you grow. Add Redis for caching and NoSQL only when your workload demands it.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>database</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>JSON vs YAML: Which Data Format Should You Use?</title>
      <dc:creator>kingfujing</dc:creator>
      <pubDate>Tue, 25 Aug 2026 11:38:36 +0000</pubDate>
      <link>https://dev.to/kingfujing/json-vs-yaml-which-data-format-should-you-use-414k</link>
      <guid>https://dev.to/kingfujing/json-vs-yaml-which-data-format-should-you-use-414k</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://devtoolshub.cloud/blog/json-vs-yaml" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — free, privacy-first online tools for developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;JSON and YAML are the two most popular data formats for developers. JSON powers almost every web API, while YAML is the default for Docker Compose, Kubernetes, GitHub Actions, and Ansible. But they solve overlapping problems in different ways — and choosing wrong can make your config files painful to maintain.&lt;/p&gt;

&lt;p&gt;In this guide, we'll compare JSON and YAML across readability, nesting, comments, anchors, and parse speed — so you can pick the right format for your next config file or API.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Quick Try:&lt;/strong&gt; Need to format or validate JSON? Use our free &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;JSON Formatter&lt;/a&gt; right in your browser.&lt;/p&gt;




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

&lt;p&gt;JSON (JavaScript Object Notation) is a &lt;strong&gt;text-based data format&lt;/strong&gt; that mirrors JavaScript object syntax. It uses curly braces, brackets, and key-value pairs, and it's the de-facto standard for web APIs — every language has a built-in JSON parser.&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;"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;"DevToolsHub"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tools"&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;"json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"base64"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"regex"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"free"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rating"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;4.8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Universal parser support. Strict syntax with no ambiguity. Great for data interchange between systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Verbose (brackets everywhere). No comments in the official spec. Hard to hand-write for complex nested configs.&lt;/p&gt;

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

&lt;p&gt;YAML (YAML Ain't Markup Language) is a &lt;strong&gt;human-friendly data format&lt;/strong&gt; that uses indentation instead of brackets. It's designed to be readable by humans at a glance, which makes it the default for configuration files across Docker, Kubernetes, and CI/CD pipelines.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Server config&lt;/span&gt;
&lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;json&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;base64&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;regex&lt;/span&gt;
&lt;span class="na"&gt;free&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;rating&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4.8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Clean, readable syntax with minimal noise. Supports comments. Has anchors (&amp;amp;) for reusing values. Native multi-line strings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Indentation-sensitive — a space can break your config. No universal parser (Python, Ruby, JS vary). Type coercion surprises (e.g., &lt;code&gt;yes&lt;/code&gt; becoming a boolean).&lt;/p&gt;

&lt;h2&gt;
  
  
  Head-to-Head Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;JSON&lt;/th&gt;
&lt;th&gt;YAML&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Readability&lt;/td&gt;
&lt;td&gt;⚠️ Verbose brackets&lt;/td&gt;
&lt;td&gt;✅ Clean indentation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comments&lt;/td&gt;
&lt;td&gt;❌ Not in spec&lt;/td&gt;
&lt;td&gt;✅ Native support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parse Speed&lt;/td&gt;
&lt;td&gt;✅ Fast (native parsers)&lt;/td&gt;
&lt;td&gt;❌ 3-10x slower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parser Support&lt;/td&gt;
&lt;td&gt;✅ Universal (built-in)&lt;/td&gt;
&lt;td&gt;⚠️ Library needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reuse / Anchors&lt;/td&gt;
&lt;td&gt;❌ None&lt;/td&gt;
&lt;td&gt;✅ Anchors &amp;amp; aliases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-line Strings&lt;/td&gt;
&lt;td&gt;⚠️ Escaping hell&lt;/td&gt;
&lt;td&gt;✅ Native (|, &amp;gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Type Safety&lt;/td&gt;
&lt;td&gt;✅ Strict types&lt;/td&gt;
&lt;td&gt;⚠️ Type coercion traps&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Parse Speed: The Real Story
&lt;/h2&gt;

&lt;p&gt;JSON parsers are &lt;strong&gt;natively built into every language&lt;/strong&gt; and optimized at the C/Rust level — &lt;code&gt;JSON.parse()&lt;/code&gt; handles millions of operations per second. YAML parsers are separate libraries and typically run &lt;strong&gt;3-10x slower&lt;/strong&gt;, because the spec is far more complex (anchors, tags, multi-document, type resolution).&lt;/p&gt;

&lt;p&gt;For config files loaded once at startup, this difference is irrelevant. For high-frequency data interchange (APIs, event streams, message queues), JSON's speed advantage is decisive.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use Each
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use JSON when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You're building a &lt;strong&gt;web API&lt;/strong&gt; or exchanging data between services&lt;/li&gt;
&lt;li&gt;Performance matters — &lt;strong&gt;high-frequency&lt;/strong&gt; parse/serialize cycles&lt;/li&gt;
&lt;li&gt;You need &lt;strong&gt;universal compatibility&lt;/strong&gt; across languages and tools&lt;/li&gt;
&lt;li&gt;Your data has &lt;strong&gt;strict types&lt;/strong&gt; (numbers vs strings must be unambiguous)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use YAML when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You're writing &lt;strong&gt;configuration files&lt;/strong&gt; humans will edit (CI/CD, Docker, K8s)&lt;/li&gt;
&lt;li&gt;You need &lt;strong&gt;comments&lt;/strong&gt; to document config options&lt;/li&gt;
&lt;li&gt;Your config has lots of &lt;strong&gt;repeated values&lt;/strong&gt; (anchors save duplication)&lt;/li&gt;
&lt;li&gt;You're defining &lt;strong&gt;complex nested structures&lt;/strong&gt; that JSON would be unreadable&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Converting Between JSON and YAML
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Python: JSON → YAML
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;

&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DevToolsHub&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;free&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tools&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;base64&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;

&lt;span class="c1"&gt;# JSON string
&lt;/span&gt;&lt;span class="n"&gt;json_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# YAML string
&lt;/span&gt;&lt;span class="n"&gt;yaml_str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default_flow_style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;yaml_str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# name: DevToolsHub
# free: true
# tools:
#   - json
#   - base64
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  JavaScript: JSON → YAML (js-yaml)
&lt;/h3&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;yaml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;js-yaml&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;json&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;DevToolsHub&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;free&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;json&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;base64&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;regex&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;yamlStr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;yaml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;json&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;yamlStr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// name: DevToolsHub&lt;/span&gt;
&lt;span class="c1"&gt;// free: true&lt;/span&gt;
&lt;span class="c1"&gt;// tools:&lt;/span&gt;
&lt;span class="c1"&gt;//   - json&lt;/span&gt;
&lt;span class="c1"&gt;//   - base64&lt;/span&gt;
&lt;span class="c1"&gt;//   - regex&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Node.js: CLI one-liner
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# JSON file to YAML on the command line&lt;/span&gt;
npx js-yaml config.json &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; config.yaml

&lt;span class="c"&gt;# YAML file to JSON&lt;/span&gt;
npx js-yaml &lt;span class="nt"&gt;--json&lt;/span&gt; config.yaml &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; config.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Verdict
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;🎯 &lt;strong&gt;Recommendation:&lt;/strong&gt; For &lt;strong&gt;data interchange (APIs, storage, messaging)&lt;/strong&gt;, use &lt;strong&gt;JSON&lt;/strong&gt; — it's faster, universal, and unambiguous. For &lt;strong&gt;human-authored configuration files&lt;/strong&gt;, use &lt;strong&gt;YAML&lt;/strong&gt; — comments, anchors, and readable indentation make it far easier to maintain. The two aren't rivals; they're tools for different jobs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Format, validate, and beautify your JSON instantly with our free &lt;a href="https://devtoolshub.cloud/tools/json-formatter" rel="noopener noreferrer"&gt;online JSON Formatter&lt;/a&gt;. It runs entirely in your browser — no server uploads, no data leaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes &amp;amp; How to Avoid Them
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Using YAML for API payloads.&lt;/strong&gt; YAML's parsing ambiguity (type coercion, indentation) makes it a bad fit for cross-system data. Use JSON for anything that leaves your process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trusting YAML's implicit typing.&lt;/strong&gt; &lt;code&gt;yes&lt;/code&gt;, &lt;code&gt;no&lt;/code&gt;, &lt;code&gt;on&lt;/code&gt;, &lt;code&gt;off&lt;/code&gt; become booleans in many parsers. Quote values when in doubt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mixing tabs and spaces in YAML.&lt;/strong&gt; YAML forbids tabs for indentation. Configure your editor to use spaces and it'll never bite you.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adding comments to JSON.&lt;/strong&gt; Not part of the spec — tools will reject them. If you need comments in a config, that's a signal to use YAML.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hand-writing JSON for big configs.&lt;/strong&gt; Nested objects with 5+ levels of brackets are error-prone. Write it in YAML and convert, or generate JSON programmatically.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is YAML a superset of JSON?
&lt;/h3&gt;

&lt;p&gt;Yes — JSON is valid YAML 1.2, so you can embed JSON directly in a YAML file. But not all YAML is valid JSON, and YAML's additional features (anchors, tags, multi-document) don't exist in JSON.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does Kubernetes use YAML instead of JSON?
&lt;/h3&gt;

&lt;p&gt;Because manifests are human-authored configuration files. YAML's comments, anchors, and readability make long Kubernetes manifests far more maintainable. Internally, Kubernetes converts YAML to JSON before processing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which is faster, JSON or YAML parsing?
&lt;/h3&gt;

&lt;p&gt;JSON parsing is typically 3-10x faster than YAML because JSON has native built-in parsers and a much simpler spec. For config files loaded once this doesn't matter; for high-frequency APIs it's decisive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I add comments to JSON files?
&lt;/h3&gt;

&lt;p&gt;Not in the official spec — standard JSON parsers reject comments. Some tools support JSONC (JSON with Comments) or JSON5, but for maximum compatibility you should use YAML if you need comments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I use YAML for my application config?
&lt;/h3&gt;

&lt;p&gt;If humans maintain the config and you need comments — yes, YAML is the better choice. If the config is machine-generated or must be validated strictly, JSON is safer and more portable.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
    <item>
      <title>JWT vs Session: Which Authentication Method Should You Use?</title>
      <dc:creator>kingfujing</dc:creator>
      <pubDate>Tue, 25 Aug 2026 11:38:35 +0000</pubDate>
      <link>https://dev.to/kingfujing/jwt-vs-session-which-authentication-method-should-you-use-3kfd</link>
      <guid>https://dev.to/kingfujing/jwt-vs-session-which-authentication-method-should-you-use-3kfd</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Originally published on &lt;a href="https://devtoolshub.cloud" rel="noopener noreferrer"&gt;DevToolsHub&lt;/a&gt; — free, privacy-first online tools for developers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every web developer eventually hits the same fork in the road: should I use &lt;strong&gt;JWT tokens&lt;/strong&gt; or &lt;strong&gt;server-side sessions&lt;/strong&gt; for authentication? It's one of the most debated topics in backend development — and the answer depends on your architecture, scale, and security requirements.&lt;/p&gt;

&lt;p&gt;In this guide, we'll compare JWT and session-based auth across scalability, security, CSRF protection, and real-world use cases — so you can pick the right approach for your next project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;strong&gt;Quick Try:&lt;/strong&gt; Have a token you want to inspect? Use our free &lt;a href="https://devtoolshub.cloud/tools/jwt-decoder" rel="noopener noreferrer"&gt;JWT Decoder&lt;/a&gt; to decode and verify tokens right in your browser.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What is JWT (JSON Web Token)?
&lt;/h2&gt;

&lt;p&gt;JWT is a &lt;strong&gt;stateless&lt;/strong&gt; authentication mechanism. When a user logs in, the server signs a JSON token containing claims (user ID, role, expiry) and hands it to the client. The client sends the token in the &lt;code&gt;Authorization&lt;/code&gt; header on every request. The server just verifies the signature — it doesn't need to store anything about the session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjM0NTYiLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE3MDAwMDAwMDB9.3Z8Z0Z0Z0Z0Z0Z0Z0Z0Z0Z0Z0Z0Z0Z0Z0Z0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Stateless and horizontally scalable. Works perfectly for mobile apps, SPAs, and microservices. No server-side lookup needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Hard to revoke before expiry. Token size adds to every request. Secret management is critical — a leaked signing key compromises everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Session-Based Authentication?
&lt;/h2&gt;

&lt;p&gt;Sessions are &lt;strong&gt;stateful&lt;/strong&gt;. The server stores session data (usually in memory, Redis, or a database) and hands the client a random opaque session ID — typically an HTTP-only cookie. On each request, the server looks up the session by ID.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Session flow (simplified)
POST /login  →  { "sessionId": "a1b2c3d4..." } stored server-side
GET /profile  →  Cookie: sid=a1b2c3d4  →  server looks up session
// Logout  →  delete session → instantly invalid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Pros:&lt;/strong&gt; Instant revocation (logout/ban works immediately). No sensitive data in the client. Smaller per-request payloads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cons:&lt;/strong&gt; Stateful — horizontal scaling requires shared storage (Redis). Requires CSRF protection for cookies. Not ideal for cross-origin mobile APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Head-to-Head Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;JWT&lt;/th&gt;
&lt;th&gt;Session&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;State&lt;/td&gt;
&lt;td&gt;✅ Stateless&lt;/td&gt;
&lt;td&gt;❌ Stateful&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scalability&lt;/td&gt;
&lt;td&gt;✅ Excellent (no shared store)&lt;/td&gt;
&lt;td&gt;⚠️ Needs Redis/DB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Revocation&lt;/td&gt;
&lt;td&gt;❌ Hard (until expiry)&lt;/td&gt;
&lt;td&gt;✅ Instant (logout/ban)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CSRF Risk&lt;/td&gt;
&lt;td&gt;✅ Low (header-based)&lt;/td&gt;
&lt;td&gt;❌ High (cookies)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payload Size&lt;/td&gt;
&lt;td&gt;❌ Larger (token in each request)&lt;/td&gt;
&lt;td&gt;✅ Tiny (just session ID)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mobile / API&lt;/td&gt;
&lt;td&gt;✅ Native fit&lt;/td&gt;
&lt;td&gt;⚠️ Awkward (cookie handling)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microservices&lt;/td&gt;
&lt;td&gt;✅ Ideal&lt;/td&gt;
&lt;td&gt;❌ Central store required&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Security: The Real Story
&lt;/h2&gt;

&lt;p&gt;The security comparison isn't as one-sided as it seems. JWT tokens live in &lt;code&gt;localStorage&lt;/code&gt; are vulnerable to &lt;strong&gt;XSS&lt;/strong&gt; — any injected script can read them. Sessions stored in &lt;strong&gt;HTTP-only cookies&lt;/strong&gt; are immune to XSS but require CSRF protection.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;XSS risk:&lt;/strong&gt; JWT in localStorage → token theft. Session in HttpOnly cookie → safe.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSRF risk:&lt;/strong&gt; Session cookie → vulnerable (needs CSRF tokens). JWT in Authorization header → immune.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token leakage:&lt;/strong&gt; JWT appears in browser history/proxies if passed in URL — always use headers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  When to Use Each
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use JWT when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You're building &lt;strong&gt;microservices&lt;/strong&gt; or a distributed system&lt;/li&gt;
&lt;li&gt;You need a &lt;strong&gt;stateless API&lt;/strong&gt; for mobile apps or third-party clients&lt;/li&gt;
&lt;li&gt;You want to avoid a &lt;strong&gt;shared session store&lt;/strong&gt; (Redis) entirely&lt;/li&gt;
&lt;li&gt;You need &lt;strong&gt;short-lived access tokens&lt;/strong&gt; + refresh token flow&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Session when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You're building a &lt;strong&gt;traditional server-rendered web app&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You need &lt;strong&gt;instant revocation&lt;/strong&gt; (admin bans, account compromise)&lt;/li&gt;
&lt;li&gt;You have a &lt;strong&gt;single server&lt;/strong&gt; or already run Redis&lt;/li&gt;
&lt;li&gt;You want the &lt;strong&gt;simplest secure default&lt;/strong&gt; for a standard web app&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Node.js / Express: JWT
&lt;/h3&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;jwt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsonwebtoken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Sign a token at login&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;15m&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Verify on every request (middleware)&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid token&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Node.js / Express: Session with Redis
&lt;/h3&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;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express-session&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;RedisStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connect-redis&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;session&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;redis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redis&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;session&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RedisStore&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SESSION_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;httpOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;sameSite&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;maxAge&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;resave&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="na"&gt;saveUninitialized&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="c1"&gt;// Logout = instant revocation&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/logout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clearCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connect.sid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Python / FastAPI: JWT
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HTTPException&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi.security&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HTTPBearer&lt;/span&gt;

&lt;span class="n"&gt;security&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HTTPBearer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;Depends&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;security&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;creds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;algorithms&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HS256&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PyJWTError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid token&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Verdict
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;🎯 &lt;strong&gt;Recommendation:&lt;/strong&gt; For &lt;strong&gt;API-first applications, mobile backends, and microservices&lt;/strong&gt;, start with &lt;strong&gt;JWT&lt;/strong&gt; — the stateless design scales without a shared store. For &lt;strong&gt;traditional server-rendered web apps&lt;/strong&gt; where you need instant revocation and the simplest secure default, stick with &lt;strong&gt;sessions&lt;/strong&gt;. Many production systems use both: sessions for the web frontend, JWTs for the API.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Inspect and debug your tokens instantly with our free &lt;a href="https://devtoolshub.cloud/tools/jwt-decoder" rel="noopener noreferrer"&gt;online JWT Decoder&lt;/a&gt;. It runs entirely in your browser — no server uploads, no data leaks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes &amp;amp; How to Avoid Them
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Storing JWTs in localStorage.&lt;/strong&gt; XSS can steal them. Prefer short-lived tokens in memory or HTTP-only cookies (with CSRF protection).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Using a weak JWT secret.&lt;/strong&gt; A brute-forceable secret means forged tokens. Use &lt;code&gt;crypto.randomBytes(32).toString('hex')&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No token expiry.&lt;/strong&gt; Long-lived tokens that never expire are a security liability. Use 10-15 minute access tokens with a refresh token flow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not handling revocation.&lt;/strong&gt; If you need to ban users instantly, sessions are simpler. For JWT, add a token blacklist or short expiry.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignoring CSRF with session cookies.&lt;/strong&gt; Always add CSRF tokens or use &lt;code&gt;SameSite=Strict&lt;/code&gt; cookies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is JWT more secure than sessions?
&lt;/h3&gt;

&lt;p&gt;Neither is inherently more secure — they have different threat models. JWT is vulnerable to XSS when stored in localStorage; sessions are vulnerable to CSRF when using cookies. Both are secure when implemented correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I revoke a JWT token before it expires?
&lt;/h3&gt;

&lt;p&gt;Not directly — JWTs are stateless by design. You can implement a token blacklist (Redis set of revoked jti values), use very short expiry with refresh tokens, or switch to sessions if instant revocation is a hard requirement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is JWT stateless really faster than sessions?
&lt;/h3&gt;

&lt;p&gt;JWT skips the server-side lookup, but signature verification (HMAC or RSA) costs CPU. Sessions with Redis are often faster in practice for high-traffic apps because lookups are O(1) and tokens stay small.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use JWT with cookies instead of localStorage?
&lt;/h3&gt;

&lt;p&gt;Yes — storing the JWT in an HTTP-only cookie protects it from XSS. You still need CSRF protection, but this hybrid gives you stateless verification with cookie-grade XSS resistance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which is better for mobile apps, JWT or sessions?
&lt;/h3&gt;

&lt;p&gt;JWT is the natural fit for mobile. Native apps handle the Authorization header cleanly, and you avoid cookie management entirely. Sessions work but require extra work for cookie storage and CSRF on mobile.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>security</category>
    </item>
  </channel>
</rss>
