<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: BysonTech</title>
    <description>The latest articles on Forem by BysonTech (@bysontech_8dd1313811a8895).</description>
    <link>https://forem.com/bysontech_8dd1313811a8895</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3682239%2F1a6fbaf7-8928-4b74-a335-2ff8192c2198.jpg</url>
      <title>Forem: BysonTech</title>
      <link>https://forem.com/bysontech_8dd1313811a8895</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bysontech_8dd1313811a8895"/>
    <language>en</language>
    <item>
      <title>How JavaScript Async Actually Works (Event Loop, Micro tasks, and Call Stack)</title>
      <dc:creator>BysonTech</dc:creator>
      <pubDate>Wed, 08 Apr 2026 23:50:06 +0000</pubDate>
      <link>https://forem.com/bysontech_8dd1313811a8895/how-javascript-async-actually-works-event-loop-micro-tasks-and-call-stack-17gb</link>
      <guid>https://forem.com/bysontech_8dd1313811a8895/how-javascript-async-actually-works-event-loop-micro-tasks-and-call-stack-17gb</guid>
      <description>&lt;p&gt;If you have ever thought:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why does &lt;code&gt;Promise.then()&lt;/code&gt; run before &lt;code&gt;setTimeout&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;Why does &lt;code&gt;await&lt;/code&gt; run “later” even though it looks synchronous?&lt;/li&gt;
&lt;li&gt;What is actually happening behind async / await?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;then you are ready to understand how JavaScript async really works.&lt;/p&gt;

&lt;p&gt;When I first struggled with “why a Promise is returned”, I realized that I could not go further without understanding the internal mechanism.&lt;/p&gt;

&lt;p&gt;In JavaScript, async behavior is built on these five concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call Stack
&lt;/li&gt;
&lt;li&gt;Web APIs
&lt;/li&gt;
&lt;li&gt;Task Queue
&lt;/li&gt;
&lt;li&gt;Microtask Queue
&lt;/li&gt;
&lt;li&gt;Event Loop
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;Promise&lt;/code&gt; and &lt;code&gt;async / await&lt;/code&gt; are just built on top of this system.&lt;/p&gt;

&lt;p&gt;Let’s break it down step by step.&lt;/p&gt;




&lt;h1&gt;
  
  
  1. JavaScript Is Single-Threaded
&lt;/h1&gt;

&lt;p&gt;JavaScript can execute only one thing at a time.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;A&lt;/span&gt;  
&lt;span class="nx"&gt;B&lt;/span&gt;  
&lt;span class="nx"&gt;C&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This order is controlled by the &lt;strong&gt;Call Stack&lt;/strong&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  2. What Is the Call Stack?
&lt;/h1&gt;

&lt;p&gt;The call stack is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a stack that keeps track of currently executing functions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It follows LIFO (Last In, First Out).&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;b&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;b&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&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="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execution order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="nf"&gt;b&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="mi"&gt;4&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The stack grows as functions are called and shrinks as they finish.&lt;/p&gt;




&lt;h1&gt;
  
  
  3. The Problem: Long-Running Tasks
&lt;/h1&gt;

&lt;p&gt;Now consider this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timeout&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="mi"&gt;0&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;start&lt;/span&gt;  
&lt;span class="nx"&gt;end&lt;/span&gt;  
&lt;span class="nx"&gt;timeout&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why does &lt;code&gt;setTimeout&lt;/code&gt; run later, even with 0ms?&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Web APIs&lt;/strong&gt; come in.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. Web APIs
&lt;/h1&gt;

&lt;p&gt;JavaScript engines (like V8) do not handle timers or network requests.&lt;/p&gt;

&lt;p&gt;Features like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;setTimeout
&lt;/li&gt;
&lt;li&gt;fetch
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;are provided by the &lt;strong&gt;browser (or runtime environment)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;setTimeout&lt;/code&gt; is called
&lt;/li&gt;
&lt;li&gt;It is handed off to Web APIs
&lt;/li&gt;
&lt;li&gt;Timer starts outside the call stack
&lt;/li&gt;
&lt;li&gt;JavaScript continues execution
&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  5. Task Queue
&lt;/h1&gt;

&lt;p&gt;When the timer finishes, the callback is not executed immediately.&lt;/p&gt;

&lt;p&gt;It is placed into the:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task Queue (Macrotask Queue)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a queue of functions waiting to be executed.&lt;/p&gt;




&lt;h1&gt;
  
  
  6. Event Loop
&lt;/h1&gt;

&lt;p&gt;The event loop is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a mechanism that checks if the call stack is empty&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run everything in the call stack
&lt;/li&gt;
&lt;li&gt;When empty → take one task from the task queue
&lt;/li&gt;
&lt;li&gt;Push it to the call stack
&lt;/li&gt;
&lt;li&gt;Repeat
&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  7. Full Async Flow
&lt;/h1&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B&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="mi"&gt;0&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;A&lt;/span&gt;  
&lt;span class="nx"&gt;C&lt;/span&gt;  
&lt;span class="nx"&gt;B&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A runs
&lt;/li&gt;
&lt;li&gt;setTimeout registers callback
&lt;/li&gt;
&lt;li&gt;C runs
&lt;/li&gt;
&lt;li&gt;call stack becomes empty
&lt;/li&gt;
&lt;li&gt;event loop pushes task
&lt;/li&gt;
&lt;li&gt;B runs
&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  8. Promise Is Special
&lt;/h1&gt;

&lt;p&gt;Here is the important part:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Promise.then()&lt;/code&gt; does NOT use the normal task queue.&lt;/p&gt;

&lt;p&gt;It uses a different queue called:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Microtask Queue&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  9. Microtasks vs Tasks
&lt;/h1&gt;

&lt;p&gt;JavaScript has two queues:&lt;/p&gt;

&lt;h3&gt;
  
  
  Task Queue (Macrotasks)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;setTimeout
&lt;/li&gt;
&lt;li&gt;setInterval
&lt;/li&gt;
&lt;li&gt;DOM events
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Microtask Queue
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Promise.then
&lt;/li&gt;
&lt;li&gt;catch
&lt;/li&gt;
&lt;li&gt;finally
&lt;/li&gt;
&lt;li&gt;queueMicrotask
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Key rule:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Microtasks run before tasks&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  10. Example
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timeout&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;promise&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;end&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;start&lt;/span&gt;  
&lt;span class="nx"&gt;end&lt;/span&gt;  
&lt;span class="nx"&gt;promise&lt;/span&gt;  
&lt;span class="nx"&gt;timeout&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because microtasks run first.&lt;/p&gt;




&lt;h1&gt;
  
  
  11. Event Loop Order (Important)
&lt;/h1&gt;

&lt;p&gt;The real execution order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run call stack
&lt;/li&gt;
&lt;li&gt;Run ALL microtasks
&lt;/li&gt;
&lt;li&gt;Run ONE task
&lt;/li&gt;
&lt;li&gt;Run microtasks again
&lt;/li&gt;
&lt;li&gt;Repeat
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the core rule.&lt;/p&gt;




&lt;h1&gt;
  
  
  12. What async Really Does
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;test&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="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is actually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;async = function that returns a Promise&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  13. What await Really Does
&lt;/h1&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B&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="nf"&gt;main&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;A&lt;/span&gt;  
&lt;span class="nx"&gt;C&lt;/span&gt;  
&lt;span class="nx"&gt;B&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;await splits the function into two parts using Promise.then&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  14. Mental Model of await
&lt;/h1&gt;

&lt;p&gt;This:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&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;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getData&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;value&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;is conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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;h1&gt;
  
  
  15. await Splits Execution
&lt;/h1&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;main&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="mi"&gt;3&lt;/span&gt;  
&lt;span class="mi"&gt;1&lt;/span&gt;  
&lt;span class="mi"&gt;4&lt;/span&gt;  
&lt;span class="mi"&gt;2&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything after &lt;code&gt;await&lt;/code&gt; becomes a microtask.&lt;/p&gt;




&lt;h1&gt;
  
  
  16. Another Example
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C&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="nf"&gt;test&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;D&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;A&lt;/span&gt;  
&lt;span class="nx"&gt;B&lt;/span&gt;  
&lt;span class="nx"&gt;D&lt;/span&gt;  
&lt;span class="nx"&gt;C&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  17. Key Insight About await
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;await does NOT block the thread&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It just:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;splits the function and schedules the rest as a microtask&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  18. Sequential vs Parallel
&lt;/h1&gt;

&lt;p&gt;Sequential:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchA&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;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchB&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parallel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="nf"&gt;fetchA&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nf"&gt;fetchB&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;Important:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parallelism depends on when the Promise starts, not when you await it&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  19. Why This Matters
&lt;/h1&gt;

&lt;p&gt;If you write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchA&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;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchB&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;fetchA runs
&lt;/li&gt;
&lt;li&gt;wait
&lt;/li&gt;
&lt;li&gt;fetchB runs
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But if you write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;aPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetchA&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;bPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetchB&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;a&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;aPromise&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b&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;bPromise&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;both start immediately.&lt;/p&gt;




&lt;h1&gt;
  
  
  20. Big Picture
&lt;/h1&gt;

&lt;p&gt;JavaScript async is built on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Call Stack → current execution
&lt;/li&gt;
&lt;li&gt;Web APIs → timers, network
&lt;/li&gt;
&lt;li&gt;Task Queue → setTimeout
&lt;/li&gt;
&lt;li&gt;Microtask Queue → Promise
&lt;/li&gt;
&lt;li&gt;Event Loop → orchestrates everything
&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  21. Final Summary
&lt;/h1&gt;

&lt;p&gt;The most important ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Promise → runs in microtask queue
&lt;/li&gt;
&lt;li&gt;setTimeout → runs in task queue
&lt;/li&gt;
&lt;li&gt;microtasks always run first
&lt;/li&gt;
&lt;li&gt;await → splits code into microtasks
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you understand this, you can explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why Promise runs before setTimeout
&lt;/li&gt;
&lt;li&gt;Why await runs “later”
&lt;/li&gt;
&lt;li&gt;Why sequential vs parallel happens
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And at that point:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;async / await stops being magic and becomes predictable.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Why JavaScript Returns a Promise: Understanding async / await from the Ground Up</title>
      <dc:creator>BysonTech</dc:creator>
      <pubDate>Sun, 05 Apr 2026 06:50:17 +0000</pubDate>
      <link>https://forem.com/bysontech_8dd1313811a8895/why-javascript-returns-a-promise-understanding-async-await-from-the-ground-up-1jnb</link>
      <guid>https://forem.com/bysontech_8dd1313811a8895/why-javascript-returns-a-promise-understanding-async-await-from-the-ground-up-1jnb</guid>
      <description>&lt;p&gt;If you have ever written async JavaScript and wondered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why is this returning a Promise?&lt;/li&gt;
&lt;li&gt;Why can’t I get the value immediately?&lt;/li&gt;
&lt;li&gt;What exactly is async / await doing?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;you are not alone.&lt;/p&gt;

&lt;p&gt;Many developers use &lt;code&gt;Promise&lt;/code&gt; and &lt;code&gt;async / await&lt;/code&gt; without fully understanding what is happening under the hood. I was the same way at first.&lt;/p&gt;

&lt;p&gt;This article breaks it down in a simple, practical way.&lt;/p&gt;




&lt;h1&gt;
  
  
  1. What Synchronous Code Means
&lt;/h1&gt;

&lt;p&gt;JavaScript runs code from top to bottom, in order.&lt;br&gt;&lt;br&gt;
This is called synchronous execution.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;C&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;A&lt;/span&gt;  
&lt;span class="nx"&gt;B&lt;/span&gt;  
&lt;span class="nx"&gt;C&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  2. Why Asynchronous Code Exists
&lt;/h1&gt;

&lt;p&gt;Some operations take time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API calls
&lt;/li&gt;
&lt;li&gt;File reading
&lt;/li&gt;
&lt;li&gt;Database access
&lt;/li&gt;
&lt;li&gt;User input
&lt;/li&gt;
&lt;li&gt;Timers
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If these were all synchronous, the UI would freeze.&lt;/p&gt;

&lt;p&gt;So JavaScript allows code to continue running without waiting for these operations to finish.&lt;br&gt;&lt;br&gt;
That is asynchronous processing.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;After 3 seconds&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="mi"&gt;3000&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;End&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Start&lt;/span&gt;  
&lt;span class="nx"&gt;End&lt;/span&gt;  
&lt;span class="nx"&gt;After&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="nx"&gt;seconds&lt;/span&gt;  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The callback runs later, so &lt;code&gt;"End"&lt;/code&gt; appears first.&lt;/p&gt;




&lt;h1&gt;
  
  
  3. What a Promise Actually Is
&lt;/h1&gt;

&lt;p&gt;A Promise solves one core problem:&lt;/p&gt;

&lt;p&gt;How do we handle a result that is not available yet?&lt;/p&gt;

&lt;p&gt;A Promise is:&lt;/p&gt;

&lt;p&gt;a value that will be available in the future&lt;/p&gt;

&lt;p&gt;You can think of it as a placeholder.&lt;/p&gt;




&lt;h2&gt;
  
  
  Promise States
&lt;/h2&gt;

&lt;p&gt;A Promise has three states:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;pending&lt;/code&gt; → still running
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fulfilled&lt;/code&gt; → success
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rejected&lt;/code&gt; → failure
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the state changes, &lt;code&gt;then()&lt;/code&gt; or &lt;code&gt;catch()&lt;/code&gt; runs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;task&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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;success&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failure&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;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  4. Why You Don’t Get the Value Immediately
&lt;/h1&gt;

&lt;p&gt;This is the most important point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getData&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&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="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;OK&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2000&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getData&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;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;pending&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The value is not ready yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Promise is not the value — it is a future value.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  5. Promise Chaining
&lt;/h1&gt;

&lt;p&gt;You can chain asynchronous steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Next step&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works, but can become hard to read.&lt;/p&gt;

&lt;p&gt;That is why &lt;code&gt;async / await&lt;/code&gt; exists.&lt;/p&gt;




&lt;h1&gt;
  
  
  6. What &lt;code&gt;async&lt;/code&gt; Means
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;async&lt;/code&gt; means:&lt;/p&gt;

&lt;p&gt;this function always returns a Promise&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;test&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the same as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  7. What &lt;code&gt;await&lt;/code&gt; Means
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;await&lt;/code&gt; means:&lt;/p&gt;

&lt;p&gt;wait for a Promise and return its value&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getData&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&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="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Data&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2000&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getData&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;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;await&lt;/code&gt; pauses the function, not the whole program.&lt;/p&gt;




&lt;h1&gt;
  
  
  8. Promise vs async / await
&lt;/h1&gt;

&lt;p&gt;Promise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="sr"&gt;/ await&lt;/span&gt;&lt;span class="err"&gt;:
&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;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getData&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;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;async / await is just a cleaner way to write Promise-based code.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  9. Error Handling
&lt;/h1&gt;

&lt;p&gt;With Promise → &lt;code&gt;catch()&lt;/code&gt;&lt;br&gt;&lt;br&gt;
With async → &lt;code&gt;try / catch&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  10. Parallel Processing
&lt;/h1&gt;

&lt;p&gt;Sequential:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchA&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;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchB&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parallel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="nf"&gt;fetchA&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nf"&gt;fetchB&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;h1&gt;
  
  
  11. Promise.allSettled
&lt;/h1&gt;

&lt;p&gt;If you need all results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;allSettled&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="nf"&gt;task1&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="nf"&gt;task2&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;h1&gt;
  
  
  12. fetch with async / await
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getUsers&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;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/users&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Request failed&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Wait for response
&lt;/li&gt;
&lt;li&gt;Wait for JSON parsing
&lt;/li&gt;
&lt;/ol&gt;




&lt;h1&gt;
  
  
  13. Common Mistakes
&lt;/h1&gt;

&lt;h2&gt;
  
  
  async returns a Promise
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;test&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="mi"&gt;123&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Promise&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  await outside async
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&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;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Error&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Missing error handling
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// may crash&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  14. When to Use new Promise
&lt;/h1&gt;

&lt;p&gt;Usually, you do not need it.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;bad&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/data&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="nf"&gt;then&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="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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&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;reject&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;good&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api/data&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="nf"&gt;then&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="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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use &lt;code&gt;new Promise&lt;/code&gt; mainly to wrap callback APIs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ms&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&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="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ms&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;h1&gt;
  
  
  15. Real-World Pitfall
&lt;/h1&gt;

&lt;p&gt;I once expected a boolean, but got a Promise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isWindows11OrLater&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="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userAgentData&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getHighEntropyValues&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;platformVersion&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;ua&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userAgentData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platform&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Windows&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&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;version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ua&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;platformVersion&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="s2"&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;0&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;13&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;isWindows11OrLater&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;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;the API itself is asynchronous, so it returns a Promise.&lt;/strong&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Promise → a future value
&lt;/li&gt;
&lt;li&gt;async → always returns a Promise
&lt;/li&gt;
&lt;li&gt;await → unwraps that value
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once this clicks, async JavaScript becomes much easier.&lt;/p&gt;

&lt;p&gt;You will use this everywhere:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API calls
&lt;/li&gt;
&lt;li&gt;data fetching
&lt;/li&gt;
&lt;li&gt;parallel execution
&lt;/li&gt;
&lt;li&gt;error handling
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding Promise first makes &lt;code&gt;async / await&lt;/code&gt; much clearer.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Designing “Just Enough” API Security for Solo Developers</title>
      <dc:creator>BysonTech</dc:creator>
      <pubDate>Mon, 29 Dec 2025 02:13:12 +0000</pubDate>
      <link>https://forem.com/bysontech_8dd1313811a8895/designing-just-enough-api-security-for-solo-developers-jkc</link>
      <guid>https://forem.com/bysontech_8dd1313811a8895/designing-just-enough-api-security-for-solo-developers-jkc</guid>
      <description>&lt;h2&gt;
  
  
  How I Avoided Overengineering While Keeping My API Safe
&lt;/h2&gt;

&lt;p&gt;API security in solo development is tricky.&lt;/p&gt;

&lt;p&gt;It’s often unclear &lt;strong&gt;how far is “enough”&lt;/strong&gt;,&lt;br&gt;&lt;br&gt;
which leads to either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;overengineering everything out of fear, or
&lt;/li&gt;
&lt;li&gt;leaving critical parts completely unprotected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my own projects, I evaluated both Firebase’s simplicity and AWS’s robustness,&lt;br&gt;&lt;br&gt;
but repeatedly ran into the same problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cost&lt;/li&gt;
&lt;li&gt;operational complexity&lt;/li&gt;
&lt;li&gt;long-term maintenance burden&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Related article: &lt;a href="https://dev.to/bysontech_8dd1313811a8895/the-obstacles-i-faced-in-personal-development-and-how-i-chose-my-tech-stack-5172"&gt;The Obstacles I Faced in Personal Development and How I Chose My Tech Stack&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;What I eventually settled on was this idea:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t aim for perfection.&lt;br&gt;&lt;br&gt;
Protect your API in layers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This article summarizes &lt;em&gt;what I decided to protect&lt;/em&gt;,&lt;br&gt;&lt;br&gt;
&lt;em&gt;what I intentionally did not&lt;/em&gt;,&lt;br&gt;&lt;br&gt;
and &lt;em&gt;why&lt;/em&gt;—based on actually building a small API as a solo developer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Target Architecture
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;React Native (client)&lt;/li&gt;
&lt;li&gt;Cloudflare Workers + Hono (API)&lt;/li&gt;
&lt;li&gt;Supabase (Auth / PostgreSQL / RLS)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The API is designed to be called from multiple client applications.&lt;/p&gt;

&lt;p&gt;Demo repository:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/umemura-dev/hono-supabase-auth-security-demo" rel="noopener noreferrer"&gt;https://github.com/umemura-dev/hono-supabase-auth-security-demo&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Security Was Not Clearly Defined at the Start
&lt;/h2&gt;

&lt;p&gt;From the beginning, I knew security mattered.&lt;br&gt;&lt;br&gt;
But I didn’t know &lt;strong&gt;how strong it needed to be&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once you start thinking about security,&lt;br&gt;&lt;br&gt;
the list of possible attacks never ends.&lt;/p&gt;

&lt;p&gt;I found myself stuck in a loop of anxiety:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What if this attack happens?”&lt;br&gt;&lt;br&gt;
“What about that scenario?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As a result, it was difficult to move forward.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Deciding the Scope Before Writing Code
&lt;/h2&gt;

&lt;p&gt;I realized that security design needs boundaries.&lt;/p&gt;

&lt;p&gt;Before implementing anything, I decided to define:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;what I would consider&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
and&lt;br&gt;&lt;br&gt;
&lt;strong&gt;what I would intentionally ignore&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. My Practical Threat Model
&lt;/h2&gt;

&lt;p&gt;This was not a formal threat model.&lt;br&gt;&lt;br&gt;
It evolved while building the API.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I assumed &lt;em&gt;would&lt;/em&gt; happen
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Unauthenticated requests&lt;/li&gt;
&lt;li&gt;Invalid or malformed parameters&lt;/li&gt;
&lt;li&gt;Requests with stolen or replayed JWTs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What I chose &lt;em&gt;not&lt;/em&gt; to assume
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Perfect secrecy of client-side code&lt;/li&gt;
&lt;li&gt;Defenses against full reverse engineering of native apps&lt;/li&gt;
&lt;li&gt;Stopping every possible attack at the API layer alone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a solo developer,&lt;br&gt;&lt;br&gt;
I limited the scope to &lt;strong&gt;what I could realistically manage&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Moving Away from “The API Must Do Everything”
&lt;/h2&gt;

&lt;p&gt;Initially, I thought:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“The API should validate everything perfectly.”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But during implementation, I realized:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bugs happen&lt;/li&gt;
&lt;li&gt;edge cases are missed&lt;/li&gt;
&lt;li&gt;future changes can weaken assumptions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I changed my mindset:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don’t rely on a single layer to be perfect.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Splitting Responsibilities by Layer
&lt;/h2&gt;

&lt;p&gt;I ended up with the following responsibility split.&lt;/p&gt;

&lt;h3&gt;
  
  
  API layer (Cloudflare Workers)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Basic request validation at the entry point&lt;/li&gt;
&lt;li&gt;JWT verification and user identification&lt;/li&gt;
&lt;li&gt;Rejecting unexpected clients&lt;/li&gt;
&lt;li&gt;Input validation&lt;/li&gt;
&lt;li&gt;Lightweight rate limiting&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Supabase Auth
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Guaranteeing authenticated users&lt;/li&gt;
&lt;li&gt;Providing consistent user IDs (UIDs)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Supabase RLS
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Row-level access control&lt;/li&gt;
&lt;li&gt;Protecting data even if the API layer makes mistakes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No single layer is trusted completely.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Why JWT Alone Was Not Enough
&lt;/h2&gt;

&lt;p&gt;JWT tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;who the user is&lt;/li&gt;
&lt;li&gt;whether they are authenticated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But it does &lt;em&gt;not&lt;/em&gt; tell you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which application sent the request&lt;/li&gt;
&lt;li&gt;whether the client was expected&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That led to this conclusion:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;users and applications should be verified separately&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I added application-level verification at the API entry point.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Keeping Request Signing “Reasonable”
&lt;/h2&gt;

&lt;p&gt;For application identification,&lt;br&gt;&lt;br&gt;
I use request signing (HMAC).&lt;/p&gt;

&lt;p&gt;However, I intentionally avoided:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;signing the request body&lt;/li&gt;
&lt;li&gt;strict nonce management&lt;/li&gt;
&lt;li&gt;perfect replay protection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead, I sign only:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;timestamp&lt;/li&gt;
&lt;li&gt;HTTP method&lt;/li&gt;
&lt;li&gt;path&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was a conscious tradeoff between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;implementation cost&lt;/li&gt;
&lt;li&gt;operational complexity&lt;/li&gt;
&lt;li&gt;actual threat level&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, since the secret key lives in the client (React Native),&lt;br&gt;&lt;br&gt;
I did not consider full HMAC-level rigor realistic for solo development.&lt;/p&gt;

&lt;p&gt;(Related article:&lt;a href="https://dev.to/bysontech_8dd1313811a8895/protecting-the-api-entry-point-with-cloudflare-workers-3gp7"&gt;Protecting the API Entry Point with Cloudflare Workers&lt;/a&gt;)&lt;/p&gt;




&lt;h2&gt;
  
  
  8. RLS as the Final Line of Defense
&lt;/h2&gt;

&lt;p&gt;No matter how careful the API design is,&lt;br&gt;&lt;br&gt;
the following will eventually happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;bugs&lt;/li&gt;
&lt;li&gt;refactoring mistakes&lt;/li&gt;
&lt;li&gt;new routes added later&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I made one rule non-negotiable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;even if the API is bypassed, other users’ data must not be accessible&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Supabase RLS enforces this at the database level.&lt;/p&gt;

&lt;p&gt;(Related article:&lt;a href="https://dev.to/bysontech_8dd1313811a8895/how-i-designed-supabase-and-row-level-security-rls-4022"&gt;How I Designed Supabase and Row Level Security (RLS)&lt;/a&gt;)&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Final Architecture (Conceptual View)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Layer 1: Client&lt;/strong&gt;&lt;br&gt;
[ React Native App ]&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JWT + Signature&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Layer 2: API&lt;/strong&gt;&lt;br&gt;
[ Cloudflare Workers API ]&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;app validation&lt;/li&gt;
&lt;li&gt;JWT verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Layer 3: Database&lt;/strong&gt;&lt;br&gt;
[ Supabase PostgreSQL ]&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RLS enforcement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;br&gt;
[ Authorized JSON Response ]&lt;/p&gt;

&lt;p&gt;Even if one layer fails,&lt;br&gt;&lt;br&gt;
&lt;strong&gt;the next layer is expected to stop the request.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This layered thinking made it much easier to decide&lt;br&gt;&lt;br&gt;
&lt;em&gt;how far security design should go&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Logging and Error Design
&lt;/h2&gt;

&lt;p&gt;Security is not only about prevention.&lt;br&gt;&lt;br&gt;
It’s also about &lt;strong&gt;being able to investigate incidents&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this demo API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;every request is assigned a requestId&lt;/li&gt;
&lt;li&gt;logs are structured JSON for future aggregation&lt;/li&gt;
&lt;li&gt;error responses to clients are minimal&lt;/li&gt;
&lt;li&gt;internal logs clearly distinguish auth and authorization failures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At the moment, logs go to &lt;code&gt;console&lt;/code&gt;,&lt;br&gt;&lt;br&gt;
but the design allows production-grade logging by simply swapping outputs.&lt;/p&gt;




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

&lt;p&gt;While building this demo API, I learned that:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;designing security “correctly” from day one is extremely difficult&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What helped was changing my approach:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;don’t design everything at once—decide the order.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The order that worked best for me:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Fix assumptions  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what is the client
&lt;/li&gt;
&lt;li&gt;who are the users
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Decide threat boundaries  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what must be protected
&lt;/li&gt;
&lt;li&gt;what is acceptable to ignore
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lock down the database  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RLS to prevent cross-user access
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Confirm user identity  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JWT authentication
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Validate requests at the API entry  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;basic validation
&lt;/li&gt;
&lt;li&gt;reject unexpected traffic
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add application-level identification if needed  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;signatures / timestamps
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Throttle unintended request bursts  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;rate limiting
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make issues traceable  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;requestId
&lt;/li&gt;
&lt;li&gt;structured logs
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By following this sequence,&lt;br&gt;&lt;br&gt;
I arrived at an API design that is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;not overengineered,&lt;br&gt;&lt;br&gt;
but difficult to break accidentally.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I hope this article helps you decide&lt;br&gt;&lt;br&gt;
&lt;em&gt;how far your own API security should go.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>architecture</category>
      <category>security</category>
    </item>
    <item>
      <title>Protecting the API Entry Point with Cloudflare Workers</title>
      <dc:creator>BysonTech</dc:creator>
      <pubDate>Mon, 29 Dec 2025 02:00:32 +0000</pubDate>
      <link>https://forem.com/bysontech_8dd1313811a8895/protecting-the-api-entry-point-with-cloudflare-workers-3gp7</link>
      <guid>https://forem.com/bysontech_8dd1313811a8895/protecting-the-api-entry-point-with-cloudflare-workers-3gp7</guid>
      <description>&lt;h2&gt;
  
  
  Verifying Application Authenticity Beyond JWT
&lt;/h2&gt;

&lt;p&gt;In this article, I describe how I designed an API that assumes multiple client applications, using the following architecture:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React Native → Cloudflare Workers (Hono) → Supabase&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A demo implementation is available here:&lt;/p&gt;

&lt;p&gt;GitHub:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/umemura-dev/hono-supabase-auth-security-demo" rel="noopener noreferrer"&gt;https://github.com/umemura-dev/hono-supabase-auth-security-demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the previous article, I explained how Supabase Auth and RLS guarantee&lt;br&gt;&lt;br&gt;
&lt;em&gt;who can access which data&lt;/em&gt; at the database layer.&lt;/p&gt;

&lt;p&gt;This article focuses on one step earlier:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;how incoming requests themselves are handled at the API entry point.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Why I Felt JWT Alone Was Not Enough
&lt;/h2&gt;

&lt;p&gt;With Supabase Auth, JWTs allow us to verify:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Which user is making this request?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, as I refined the design, several concerns emerged:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JWT proves &lt;em&gt;user identity&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;It does not prove &lt;em&gt;which application&lt;/em&gt; sent the request&lt;/li&gt;
&lt;li&gt;If a token is leaked, requests can still be made as a valid user&lt;/li&gt;
&lt;li&gt;Bots, scripts, and unintended clients are indistinguishable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;user authenticity and application authenticity are separate concerns.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;JWT is essential, but relying on it alone felt insufficient.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Introducing “Application Authentication”
&lt;/h2&gt;

&lt;p&gt;To address this, I separated responsibilities as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JWT&lt;/strong&gt;: who the user is
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App Guard&lt;/strong&gt;: which application is making the request
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In addition to user authentication, the API verifies:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Is this request coming from a pre-approved application?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This mechanism is referred to here as &lt;strong&gt;App Guard&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. App Guard Specification in the Demo
&lt;/h2&gt;

&lt;p&gt;App Guard uses the following request headers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;X-App-Id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-App-Timestamp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;X-App-Signature&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each serves a distinct purpose.&lt;/p&gt;

&lt;h3&gt;
  
  
  X-App-Id
&lt;/h3&gt;

&lt;p&gt;Identifies which client application is sending the request.&lt;br&gt;&lt;br&gt;
The server maintains pre-registered configurations per app.&lt;/p&gt;

&lt;h3&gt;
  
  
  X-App-Timestamp
&lt;/h3&gt;

&lt;p&gt;Indicates when the request was created.&lt;br&gt;&lt;br&gt;
This helps prevent replay attacks using old requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  X-App-Signature
&lt;/h3&gt;

&lt;p&gt;Verifies that the request was not tampered with in transit.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. The Concept of Request Signing
&lt;/h2&gt;

&lt;p&gt;Each client application shares a &lt;strong&gt;secret key&lt;/strong&gt; with the server.&lt;/p&gt;

&lt;p&gt;When sending a request:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The app computes a value from the request content and the secret key&lt;/li&gt;
&lt;li&gt;The value is sent as &lt;code&gt;X-App-Signature&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The server performs the same calculation&lt;/li&gt;
&lt;li&gt;If both values match, the request is considered legitimate&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Third parties cannot forge valid requests without the secret&lt;/li&gt;
&lt;li&gt;Any request modification breaks the signature&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Internally, this uses a standard signing algorithm (HMAC),&lt;br&gt;&lt;br&gt;
but this article focuses on the &lt;em&gt;design rationale&lt;/em&gt;, not the cryptographic details.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Why This Signing Format Was Chosen
&lt;/h2&gt;

&lt;p&gt;The signature input is constructed as:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;${timestamp}.${METHOD}.${path}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This format was chosen deliberately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why include the timestamp
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Prevents replaying old requests&lt;/li&gt;
&lt;li&gt;Makes requests valid only for a short time window&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why include METHOD and path
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Prevents confusion between GET and POST&lt;/li&gt;
&lt;li&gt;Prevents reuse against different endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why the request body is excluded
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;JSON ordering and formatting differences easily break signatures&lt;/li&gt;
&lt;li&gt;Increases implementation and operational complexity&lt;/li&gt;
&lt;li&gt;Not cost-effective for a small-scale API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of perfection,&lt;br&gt;&lt;br&gt;
&lt;strong&gt;a balance between security and maintainability was prioritized.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Why STRICT and LENIENT Modes Exist
&lt;/h2&gt;

&lt;p&gt;App Guard supports multiple validation levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;STRICT&lt;/strong&gt;: timestamp and signature required&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LENIENT&lt;/strong&gt;: timestamp only&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NONE&lt;/strong&gt;: validation skipped (development use)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Applying maximum strictness everywhere can be overkill.&lt;br&gt;&lt;br&gt;
This flexibility allows each application to choose an appropriate security level without excessive overhead.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Implementation Approach with Cloudflare Workers (Hono)
&lt;/h2&gt;

&lt;p&gt;App Guard is implemented as a Hono middleware:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Runs before all routes&lt;/li&gt;
&lt;li&gt;Immediately returns 401 / 403 on failure&lt;/li&gt;
&lt;li&gt;Logs App-Id and failure reasons&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This design allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API handlers to focus purely on business logic&lt;/li&gt;
&lt;li&gt;Security logic to be centralized and consistent&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8. Responsibility Split: App Guard / JWT / RLS
&lt;/h2&gt;

&lt;p&gt;Security in this API is layered, not monolithic.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;App Guard&lt;/td&gt;
&lt;td&gt;Is this a legitimate application?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JWT&lt;/td&gt;
&lt;td&gt;Is this a legitimate user?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RLS&lt;/td&gt;
&lt;td&gt;Can this user access this data?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Even if one layer is compromised,&lt;br&gt;&lt;br&gt;
&lt;strong&gt;the next layer is expected to stop the request.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Important Limitations
&lt;/h2&gt;

&lt;p&gt;This App Guard design assumes the client-side secret key remains protected.&lt;/p&gt;

&lt;p&gt;If a client application is reverse-engineered and the secret leaks,&lt;br&gt;&lt;br&gt;
valid signatures can still be generated.&lt;/p&gt;

&lt;p&gt;This means App Guard alone is &lt;strong&gt;not a perfect defense&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this demo API, the weakness is mitigated by combining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mandatory Supabase Auth (email/password)&lt;/li&gt;
&lt;li&gt;JWT-based authenticated users&lt;/li&gt;
&lt;li&gt;RLS enforcing “only your own data” at the database level&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unauthenticated users cannot access data&lt;/li&gt;
&lt;li&gt;Authenticated users cannot access others’ data&lt;/li&gt;
&lt;li&gt;A leaked App Guard secret alone does not lead to data exposure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rather than relying on any single mechanism,&lt;br&gt;&lt;br&gt;
this design emphasizes &lt;strong&gt;defense in depth&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Summary
&lt;/h2&gt;

&lt;p&gt;In this demo API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JWT verifies users&lt;/li&gt;
&lt;li&gt;App Guard verifies applications&lt;/li&gt;
&lt;li&gt;RLS enforces data access rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even small APIs can achieve layered security&lt;br&gt;&lt;br&gt;
with careful responsibility separation.&lt;/p&gt;

&lt;p&gt;Cloudflare Workers are particularly well-suited for&lt;br&gt;&lt;br&gt;
&lt;strong&gt;controlling and validating requests at the API entry point&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;All concepts discussed here are implemented in the following repository:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloudflare Workers + Hono API&lt;/li&gt;
&lt;li&gt;Supabase Auth (JWT) + PostgreSQL RLS&lt;/li&gt;
&lt;li&gt;App Guard (signature-based client authentication)&lt;/li&gt;
&lt;li&gt;CI passing (Biome / TypeScript / Tests)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitHub:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/umemura-dev/hono-supabase-auth-security-demo" rel="noopener noreferrer"&gt;https://github.com/umemura-dev/hono-supabase-auth-security-demo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>serverless</category>
      <category>security</category>
      <category>architecture</category>
    </item>
    <item>
      <title>How I Designed Supabase and Row Level Security (RLS)</title>
      <dc:creator>BysonTech</dc:creator>
      <pubDate>Mon, 29 Dec 2025 01:53:12 +0000</pubDate>
      <link>https://forem.com/bysontech_8dd1313811a8895/how-i-designed-supabase-and-row-level-security-rls-4022</link>
      <guid>https://forem.com/bysontech_8dd1313811a8895/how-i-designed-supabase-and-row-level-security-rls-4022</guid>
      <description>&lt;h2&gt;
  
  
  Designing a Secure API with Cloudflare Workers × Supabase
&lt;/h2&gt;

&lt;p&gt;In this article, I explain &lt;strong&gt;how I approached Supabase and RLS, and how I incorporated them into my API design&lt;/strong&gt;, based on a personal project built with:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React Native → Cloudflare Workers (Hono) → Supabase&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The API assumes a simple use case: &lt;em&gt;user-specific notes&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
Supabase is powerful but very flexible, which makes it difficult to decide &lt;strong&gt;how much responsibility to delegate to it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This article exists to clarify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;where I chose to rely on Supabase,&lt;/li&gt;
&lt;li&gt;where I deliberately did not,&lt;/li&gt;
&lt;li&gt;and why I made those decisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The concepts discussed here are demonstrated in the following repository:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/umemura-dev/hono-supabase-auth-security-demo" rel="noopener noreferrer"&gt;https://github.com/umemura-dev/hono-supabase-auth-security-demo&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. How I Positioned Supabase (Initial Design Principles)
&lt;/h2&gt;

&lt;p&gt;Supabase provides many features out of the box: database, authentication, storage, and auto-generated APIs.&lt;br&gt;&lt;br&gt;
Without clear boundaries, it’s easy for responsibilities to blur and the system to become complex.&lt;/p&gt;

&lt;p&gt;So I fixed the following principles at the very beginning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 1
&lt;/h3&gt;

&lt;p&gt;Supabase is responsible for &lt;strong&gt;data integrity and safety&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 2
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Final access decisions must always be enforced by RLS&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 3
&lt;/h3&gt;

&lt;p&gt;Business logic, input validation, and error handling live in &lt;strong&gt;Workers (the API layer)&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Principle 4
&lt;/h3&gt;

&lt;p&gt;Client-side privileges are kept minimal, and &lt;strong&gt;Service Role keys are never exposed&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By defining these four rules, each layer’s responsibility became clear,&lt;br&gt;&lt;br&gt;
and I avoided pushing application logic into Supabase unnecessarily.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Supabase Components Used in This Project
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Auth (Authentication)
&lt;/h3&gt;

&lt;p&gt;The role of Supabase Auth in this design is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;to reliably identify the user (UID).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On the Workers side, the flow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Extract the JWT from the &lt;code&gt;Authorization&lt;/code&gt; header
&lt;/li&gt;
&lt;li&gt;Verify its signature using Supabase’s &lt;code&gt;JWT_SECRET&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Treat the &lt;code&gt;sub&lt;/code&gt; claim (UID) as &lt;code&gt;userId&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This &lt;code&gt;userId&lt;/code&gt; is stored in the request context and reused for database operations.&lt;/p&gt;




&lt;h3&gt;
  
  
  Database (PostgreSQL)
&lt;/h3&gt;

&lt;p&gt;This demo uses a single table, &lt;code&gt;demo_notes&lt;/code&gt;,&lt;br&gt;&lt;br&gt;
designed to store &lt;em&gt;user-specific data&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Example columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;id
&lt;/li&gt;
&lt;li&gt;user_id
&lt;/li&gt;
&lt;li&gt;title
&lt;/li&gt;
&lt;li&gt;body
&lt;/li&gt;
&lt;li&gt;created_at
&lt;/li&gt;
&lt;li&gt;updated_at
&lt;/li&gt;
&lt;li&gt;deleted_at
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;deleted_at&lt;/code&gt; column enables &lt;strong&gt;soft deletes&lt;/strong&gt;, avoiding physical row deletion.&lt;/p&gt;




&lt;h3&gt;
  
  
  RLS (Row Level Security)
&lt;/h3&gt;

&lt;p&gt;RLS is a native PostgreSQL feature that determines:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Is this user allowed to access this row?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Supabase tightly integrates Auth and RLS,&lt;br&gt;&lt;br&gt;
allowing the JWT’s UID (&lt;code&gt;sub&lt;/code&gt;) to be referenced as &lt;code&gt;auth.uid()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Even if Workers validates &lt;code&gt;userId&lt;/code&gt;,&lt;br&gt;&lt;br&gt;
without RLS there would still be a risk of data exposure if a malicious client accessed Supabase directly.&lt;/p&gt;

&lt;p&gt;For that reason, &lt;strong&gt;RLS is always treated as the final defensive layer&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Example RLS Policies (demo_notes)
&lt;/h2&gt;

&lt;p&gt;Below is a minimal RLS setup used in this project.&lt;br&gt;&lt;br&gt;
In real-world systems, you would typically extend this with read-only roles, admin roles, etc.&lt;/p&gt;

&lt;p&gt;All policies use &lt;strong&gt;&lt;code&gt;to authenticated&lt;/code&gt;&lt;/strong&gt;, meaning:&lt;br&gt;
only users authenticated via Supabase Auth are eligible.&lt;/p&gt;

&lt;p&gt;This cleanly blocks unauthenticated or malicious access.&lt;/p&gt;




&lt;h3&gt;
  
  
  SELECT (Only fetch your own notes)
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create policy "select_own_notes"
on demo_notes
for select
to authenticated
using (
  auth.uid() = user_id
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  INSERT (Only create notes for yourself)
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create policy "insert_own_notes"
on demo_notes
for insert
to authenticated
with check (
  auth.uid() = user_id
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  UPDATE (Only update your own notes)
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create policy "update_own_notes"
on demo_notes
for update
to authenticated
using (auth.uid() = user_id)
with check (auth.uid() = user_id);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note:&lt;br&gt;&lt;br&gt;
DELETE is not exposed via the API.&lt;br&gt;&lt;br&gt;
Instead, notes are soft-deleted by updating &lt;code&gt;deleted_at&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. How I Designed the Workers (Hono API)
&lt;/h2&gt;

&lt;p&gt;Responsibilities are clearly split as follows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Workers Responsibilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;JWT verification (authentication)&lt;/li&gt;
&lt;li&gt;Extracting &lt;code&gt;userId&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Input validation (Valibot)&lt;/li&gt;
&lt;li&gt;Application-specific logic (e.g. soft delete)&lt;/li&gt;
&lt;li&gt;Preparing data for Supabase&lt;/li&gt;
&lt;li&gt;Logging, rate limiting, error handling&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Supabase (RLS) Responsibilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Determining row-level access permissions&lt;/li&gt;
&lt;li&gt;Blocking unauthorized access even if the API layer is bypassed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No matter how careful the Workers layer is,&lt;br&gt;&lt;br&gt;
it can never be considered &lt;em&gt;perfectly secure&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;By enabling RLS, I ensure that &lt;strong&gt;even if a request reaches the database, other users’ data remains inaccessible&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Why I Use Supabase RLS (Compared to Plain PostgreSQL)
&lt;/h2&gt;

&lt;p&gt;RLS is available in PostgreSQL everywhere,&lt;br&gt;&lt;br&gt;
but I chose Supabase for three main reasons.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automatic Auth–RLS Integration
&lt;/h3&gt;

&lt;p&gt;Supabase provides a built-in bridge between JWTs and &lt;code&gt;auth.uid()&lt;/code&gt;,&lt;br&gt;&lt;br&gt;
dramatically reducing design and implementation complexity.&lt;/p&gt;




&lt;h3&gt;
  
  
  Safe Even with Direct Client Access
&lt;/h3&gt;

&lt;p&gt;Even when using Supabase’s official PostgREST API or client SDKs,&lt;br&gt;&lt;br&gt;
RLS policies are always enforced.&lt;/p&gt;

&lt;p&gt;Security does not depend on routing everything through Workers.&lt;/p&gt;

&lt;p&gt;The client SDK also supports automatic token refresh,&lt;br&gt;&lt;br&gt;
which simplifies client-side implementation.&lt;/p&gt;

&lt;p&gt;That said, designing a system that safely supports &lt;em&gt;direct access&lt;/em&gt; requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;careful RLS design,&lt;/li&gt;
&lt;li&gt;query design,&lt;/li&gt;
&lt;li&gt;cache strategies,&lt;/li&gt;
&lt;li&gt;and well-defined permission boundaries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since this project focuses on &lt;strong&gt;API security design&lt;/strong&gt;,&lt;br&gt;&lt;br&gt;
I intentionally centralized access through Workers.&lt;/p&gt;




&lt;h3&gt;
  
  
  Strong Security Even for Personal Projects
&lt;/h3&gt;

&lt;p&gt;RLS policies are defined in simple SQL and can be customized with conditions.&lt;br&gt;&lt;br&gt;
Once you understand the syntax, it becomes relatively easy&lt;br&gt;&lt;br&gt;
to enforce strong guarantees—even in small personal projects.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Summary: What This Architecture Prioritizes
&lt;/h2&gt;

&lt;p&gt;Although this is a small demo project, the design emphasizes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Workers (API) handle &lt;em&gt;application behavior&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;RLS (DB) provides the &lt;em&gt;final security boundary&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Supabase Auth establishes &lt;em&gt;user identity&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this structure,&lt;br&gt;&lt;br&gt;
I believe the risk of catastrophic data leaks is significantly reduced.&lt;/p&gt;

&lt;p&gt;Going forward, I plan to expand on this foundation by documenting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;request signing strategies,&lt;/li&gt;
&lt;li&gt;and additional API-side security patterns.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Demo Implementation
&lt;/h2&gt;

&lt;p&gt;Everything described in this article is implemented in the following repository:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloudflare Workers + Hono API&lt;/li&gt;
&lt;li&gt;Supabase Auth (JWT) + PostgreSQL RLS&lt;/li&gt;
&lt;li&gt;App Guard (signature-based client authentication)&lt;/li&gt;
&lt;li&gt;CI passing (Biome / TypeScript / Tests)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitHub:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/umemura-dev/hono-supabase-auth-security-demo" rel="noopener noreferrer"&gt;https://github.com/umemura-dev/hono-supabase-auth-security-demo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>serverless</category>
      <category>database</category>
    </item>
    <item>
      <title>The Obstacles I Faced in Personal Development and How I Chose My Tech Stack</title>
      <dc:creator>BysonTech</dc:creator>
      <pubDate>Sun, 28 Dec 2025 23:28:38 +0000</pubDate>
      <link>https://forem.com/bysontech_8dd1313811a8895/the-obstacles-i-faced-in-personal-development-and-how-i-chose-my-tech-stack-5172</link>
      <guid>https://forem.com/bysontech_8dd1313811a8895/the-obstacles-i-faced-in-personal-development-and-how-i-chose-my-tech-stack-5172</guid>
      <description>&lt;p&gt;This article is a companion piece to my earlier post:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/bysontech_8dd1313811a8895/comparing-api-architecture-choices-a-technical-evaluation-of-six-setups-tested-in-personal-4o63"&gt;&lt;strong&gt;“Comparing API Architecture Choices: A Technical Evaluation of Six Setups Tested in Personal Development”&lt;/strong&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;While that article focused on &lt;em&gt;technical pros and cons&lt;/em&gt;,&lt;br&gt;&lt;br&gt;
this one documents &lt;strong&gt;my personal decision-making process&lt;/strong&gt;:&lt;br&gt;
how I chose certain architectures, why I abandoned others,&lt;br&gt;
where I hit walls, and what I learned along the way.&lt;/p&gt;

&lt;p&gt;Rather than listing abstract reasons, this article focuses on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how my understanding evolved,&lt;/li&gt;
&lt;li&gt;where I got stuck,&lt;/li&gt;
&lt;li&gt;and why I changed direction at each stage.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1. Early Stage: I Didn’t Even Think About APIs or Backends
&lt;/h2&gt;

&lt;p&gt;The first thing I tried to build was a small shopping list app.&lt;br&gt;&lt;br&gt;
At that point, I didn’t think an API or server was necessary at all.&lt;/p&gt;

&lt;p&gt;My assumptions were simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It only needs to work on an iPhone&lt;/li&gt;
&lt;li&gt;Local storage should be enough&lt;/li&gt;
&lt;li&gt;The priority is to build screens and make something visible&lt;/li&gt;
&lt;li&gt;Backend systems feel optional&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With that mindset, I started development assuming a &lt;strong&gt;Swift-only, standalone app&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. First Turning Point: I Didn’t Know How to Share Data
&lt;/h2&gt;

&lt;p&gt;A few days into development, a new requirement appeared:&lt;/p&gt;

&lt;p&gt;“I want to share the shopping list with my family.”&lt;/p&gt;

&lt;p&gt;At that moment, it became obvious that local storage alone wouldn’t work.&lt;/p&gt;

&lt;p&gt;That’s when I first thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Maybe I need a database.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, my knowledge of APIs and backend systems was very limited.&lt;br&gt;
In my day job, I had only worked with on-premise systems,&lt;br&gt;
and I barely understood the concept of serverless architectures.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Trying Firebase — and Starting to See Its Limits
&lt;/h2&gt;

&lt;p&gt;While researching databases for Swift, Firebase was the first option I encountered.&lt;br&gt;
It was easy to set up, came with authentication, and looked very beginner-friendly.&lt;/p&gt;

&lt;p&gt;But as the app idea evolved, several problems became clear.&lt;/p&gt;

&lt;h3&gt;
  
  
  Firestore (NoSQL) Didn’t Match My Requirements
&lt;/h3&gt;

&lt;p&gt;For features like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;group-based data sharing,&lt;/li&gt;
&lt;li&gt;managing multiple lists,&lt;/li&gt;
&lt;li&gt;permission control,&lt;/li&gt;
&lt;li&gt;frequently updated records,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;a &lt;strong&gt;relational database&lt;/strong&gt; felt much more appropriate.&lt;/p&gt;

&lt;p&gt;Firebase was convenient, but it didn’t align with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an RDB-centered design,&lt;/li&gt;
&lt;li&gt;or my mental model for future expansion.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Moving from Swift to React Native: A Change in Assumptions
&lt;/h2&gt;

&lt;p&gt;Initially, I was building only for iOS.&lt;br&gt;
Later, I realized that React Native would allow Android support as well.&lt;/p&gt;

&lt;p&gt;I switched from Swift to React Native.&lt;br&gt;
This unified the frontend, but also made one requirement unavoidable:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I need a proper relational database.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At this stage, it became clear that I had to design a system&lt;br&gt;
that could reliably connect to an RDB.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Discovering Supabase and Serverless RDBs
&lt;/h2&gt;

&lt;p&gt;Around the time I felt Firebase wasn’t a good fit,&lt;br&gt;
I discovered Supabase and learned that PostgreSQL could be used in a serverless way.&lt;/p&gt;

&lt;p&gt;What stood out was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Serverless-friendly architecture&lt;/li&gt;
&lt;li&gt;PostgreSQL, which I was already familiar with&lt;/li&gt;
&lt;li&gt;Built-in Row Level Security (RLS)&lt;/li&gt;
&lt;li&gt;A generous free tier&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Being able to use an RDB at low cost was very appealing for personal development.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Realizing the Limits of Direct Supabase Access
&lt;/h2&gt;

&lt;p&gt;At first, I connected React Native directly to Supabase.&lt;br&gt;
But once I started using it seriously, several issues surfaced.&lt;/p&gt;

&lt;h3&gt;
  
  
  No API Layer
&lt;/h3&gt;

&lt;p&gt;Business logic and shared processing couldn’t live on the server.&lt;br&gt;
As a result, complexity accumulated on the client side.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security Design Was Hard
&lt;/h3&gt;

&lt;p&gt;I initially embedded the Supabase anon key directly in the app.&lt;br&gt;
This setup itself is not inherently wrong,&lt;br&gt;
but with my level of knowledge, managing keys and security&lt;br&gt;
without a backend layer felt risky.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Need for a Shared Backend Emerged
&lt;/h3&gt;

&lt;p&gt;As I started thinking about multiple apps,&lt;br&gt;
I realized that direct client access would not scale well.&lt;/p&gt;

&lt;p&gt;Supabase itself was great,&lt;br&gt;
but &lt;strong&gt;a direct-connection architecture had clear limits&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Considering FastAPI + AWS — and Facing Cost Reality
&lt;/h2&gt;

&lt;p&gt;Wanting a proper API foundation,&lt;br&gt;
I started considering &lt;strong&gt;FastAPI + AWS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What I initially imagined was a fairly “enterprise-style” setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API Gateway or ALB&lt;/li&gt;
&lt;li&gt;FastAPI running on EC2 or containers&lt;/li&gt;
&lt;li&gt;RDS (PostgreSQL) or Aurora Serverless v2&lt;/li&gt;
&lt;li&gt;A private VPC-based architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As I researched further, one issue became obvious.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Running Cost Would Be Too High
&lt;/h3&gt;

&lt;p&gt;AWS can be inexpensive if you use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API Gateway&lt;/li&gt;
&lt;li&gt;Lambda&lt;/li&gt;
&lt;li&gt;DynamoDB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But my mental model was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;always-on RDBs,&lt;/li&gt;
&lt;li&gt;VPC networking,&lt;/li&gt;
&lt;li&gt;monitoring and production-grade setups.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a small personal project,&lt;br&gt;
this felt &lt;strong&gt;too close to enterprise infrastructure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;From this point on, cost awareness became a major decision factor.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Trying Next.js API Routes — and Letting Them Go
&lt;/h2&gt;

&lt;p&gt;While looking for a lower-cost alternative,&lt;br&gt;
I found Vercel and Next.js API Routes.&lt;/p&gt;

&lt;p&gt;At first, this seemed perfect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript-based API development&lt;/li&gt;
&lt;li&gt;Easy Git and Supabase integration&lt;/li&gt;
&lt;li&gt;Simple deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I moved forward with this approach,&lt;br&gt;
but soon encountered problems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSR / RSC billing was hard to avoid&lt;/li&gt;
&lt;li&gt;My expected traffic and usage pattern would exhaust free tiers quickly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also realized that Next.js works best&lt;br&gt;
when frontend and API are tightly integrated,&lt;br&gt;
which didn’t match my goal of an API-focused backend.&lt;/p&gt;

&lt;p&gt;At this point, the conclusion was clear:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I need an API platform that is API-only by design.”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  9. Discovering Cloudflare Workers — Everything Clicked
&lt;/h2&gt;

&lt;p&gt;When I started exploring Cloudflare Workers,&lt;br&gt;
it immediately felt like a good fit.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large free tier&lt;/li&gt;
&lt;li&gt;Extremely low latency&lt;/li&gt;
&lt;li&gt;Fully serverless, no maintenance&lt;/li&gt;
&lt;li&gt;KV and Durable Objects available&lt;/li&gt;
&lt;li&gt;Hono looked lightweight and expressive&lt;/li&gt;
&lt;li&gt;Easy integration with Supabase&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Problems that had been scattered across previous architectures&lt;br&gt;
suddenly felt unified.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Adopting Workers × Hono — Finally a Coherent System
&lt;/h2&gt;

&lt;p&gt;Once I moved the API layer to Workers × Hono,&lt;br&gt;
multiple issues were resolved at once.&lt;/p&gt;

&lt;h3&gt;
  
  
  Centralized API Logic
&lt;/h3&gt;

&lt;p&gt;Signing, logging, validation, and rate limiting&lt;br&gt;
could all live in the API layer,&lt;br&gt;
making both security and operations easier to reason about.&lt;/p&gt;

&lt;h3&gt;
  
  
  No Need to Distribute anon Keys to Clients
&lt;/h3&gt;

&lt;p&gt;This was the biggest turning point.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defense in Depth with Supabase RLS
&lt;/h3&gt;

&lt;p&gt;Combining API-level checks with RLS&lt;br&gt;
gave me confidence in the security model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaling and Cost Were No Longer Concerns
&lt;/h3&gt;

&lt;p&gt;This finally felt like an architecture&lt;br&gt;
designed for personal development.&lt;/p&gt;

&lt;p&gt;Although Hono requires more manual implementation,&lt;br&gt;
my experience maintaining custom frameworks at work&lt;br&gt;
made this manageable.&lt;/p&gt;

&lt;p&gt;At this point, I concluded that:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React Native × Cloudflare Workers × Hono × Supabase&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;was the best solution for my needs.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Reflections on the Decision Process
&lt;/h2&gt;

&lt;p&gt;The final architecture wasn’t obvious from the start.&lt;br&gt;
It emerged through repeated trial, failure, and adjustment.&lt;/p&gt;

&lt;p&gt;Looking back, several lessons stand out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I didn’t even understand the need for APIs at first&lt;/li&gt;
&lt;li&gt;Firebase is convenient, but has clear long-term limits&lt;/li&gt;
&lt;li&gt;Supabase is powerful, but needs an API layer&lt;/li&gt;
&lt;li&gt;AWS is excellent, but often overkill for personal projects&lt;/li&gt;
&lt;li&gt;Cloudflare Workers align extremely well with personal development needs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  12. Relationship to the Comparison Article
&lt;/h2&gt;

&lt;p&gt;This article documents &lt;em&gt;how I thought and why I decided&lt;/em&gt;,&lt;br&gt;
based on hands-on experience.&lt;/p&gt;

&lt;p&gt;For a more objective, technical comparison,&lt;br&gt;
see the related article here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/bysontech_8dd1313811a8895/comparing-api-architecture-choices-a-technical-evaluation-of-six-setups-tested-in-personal-4o63"&gt;https://dev.to/bysontech_8dd1313811a8895/comparing-api-architecture-choices-a-technical-evaluation-of-six-setups-tested-in-personal-4o63&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;I’ve now settled on a stack built around:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;React Native × Cloudflare Workers × Hono × Supabase&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Going forward, I plan to use this API foundation&lt;br&gt;
to support multiple small applications.&lt;/p&gt;

&lt;p&gt;This article records one part of that journey.&lt;br&gt;
If you have suggestions or alternative approaches,&lt;br&gt;
I’d love to hear them in the comments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update
&lt;/h3&gt;

&lt;p&gt;A demo API based on this architecture is now available:&lt;br&gt;
&lt;a href="https://github.com/umemura-dev/hono-supabase-auth-security-demo" rel="noopener noreferrer"&gt;https://github.com/umemura-dev/hono-supabase-auth-security-demo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>serverless</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Comparing API Architecture Choices: A Technical Evaluation of Six Setups Tested in Personal Development</title>
      <dc:creator>BysonTech</dc:creator>
      <pubDate>Sun, 28 Dec 2025 22:43:53 +0000</pubDate>
      <link>https://forem.com/bysontech_8dd1313811a8895/comparing-api-architecture-choices-a-technical-evaluation-of-six-setups-tested-in-personal-4o63</link>
      <guid>https://forem.com/bysontech_8dd1313811a8895/comparing-api-architecture-choices-a-technical-evaluation-of-six-setups-tested-in-personal-4o63</guid>
      <description>&lt;h2&gt;
  
  
  API Architecture Comparison for Personal Projects
&lt;/h2&gt;

&lt;p&gt;When I first started personal development, I assumed the app could be mostly self-contained.&lt;br&gt;&lt;br&gt;
However, as requirements such as data sharing, user authentication, and multi-app expansion grew,&lt;br&gt;&lt;br&gt;
it became necessary to select a proper backend (API) and serverless infrastructure.&lt;/p&gt;

&lt;p&gt;After evaluating multiple setups — including Swift-only, Firebase, FastAPI, direct Supabase access, and Next.js —&lt;br&gt;&lt;br&gt;
I ultimately concluded that &lt;strong&gt;React Native × Hono × Cloudflare Workers × Supabase&lt;/strong&gt; was the optimal architecture.&lt;/p&gt;

&lt;p&gt;This article objectively summarizes the characteristics of each option and explains the technical reasons for adoption or rejection.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Selection Criteria
&lt;/h2&gt;

&lt;p&gt;The API architecture was evaluated based on the following requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Functional Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;APIs usable from both iOS and Android&lt;/li&gt;
&lt;li&gt;Support for guest users and authenticated users&lt;/li&gt;
&lt;li&gt;Persistent data storage (RDB required)&lt;/li&gt;
&lt;li&gt;A shared API used by multiple small applications&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Non-Functional Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Affordable for long-term personal development&lt;/li&gt;
&lt;li&gt;Protection against unauthorized access at the API level&lt;/li&gt;
&lt;li&gt;Scalability toward multi-tenant / SaaS use&lt;/li&gt;
&lt;li&gt;Low operational and maintenance overhead&lt;/li&gt;
&lt;li&gt;Preference for a serverless architecture&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Evaluated Architectures
&lt;/h2&gt;

&lt;p&gt;Each candidate architecture is reviewed below, along with an assessment of how well it meets the requirements.&lt;/p&gt;




&lt;h2&gt;
  
  
  2-1. Swift (iOS Only)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;A native iOS app built using Swift only, with data stored locally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evaluation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fast UI development&lt;/li&gt;
&lt;li&gt;High performance due to native execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons (Requirement Mismatch)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No Android support → fails cross-platform requirement&lt;/li&gt;
&lt;li&gt;Cannot include RDB or API layer → fails data-sharing requirement&lt;/li&gt;
&lt;li&gt;Relying solely on app-side security is inappropriate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;→ &lt;strong&gt;Rejected due to unmet requirements&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2-2. Swift + Firebase
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Uses Firebase Authentication and Firestore as the backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evaluation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Low learning curve&lt;/li&gt;
&lt;li&gt;Fast development with SDK integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons (Data Requirement Mismatch)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No Android support&lt;/li&gt;
&lt;li&gt;Firestore does not satisfy RDB requirements (joins and normalization are difficult)&lt;/li&gt;
&lt;li&gt;Security rules become complex and fragile at scale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;→ &lt;strong&gt;Rejected due to RDB and scalability constraints&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2-3. React Native + Firebase
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;A cross-platform React Native app connected directly to Firebase Authentication and Firestore.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evaluation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cross-platform support&lt;/li&gt;
&lt;li&gt;Very fast development speed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons (API Requirement Mismatch)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firestore does not meet RDB requirements&lt;/li&gt;
&lt;li&gt;Direct client access prevents building a proper API logic layer&lt;/li&gt;
&lt;li&gt;Audit logs, signatures, and advanced security logic cannot be enforced server-side&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;→ &lt;strong&gt;Rejected due to insufficient security architecture&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2-4. React Native + FastAPI + AWS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;FastAPI (Python) used as the API layer, with AWS services such as RDS, Lambda, and VPC.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evaluation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enterprise-grade security design&lt;/li&gt;
&lt;li&gt;Highly flexible business logic&lt;/li&gt;
&lt;li&gt;Broad database options (PostgreSQL, MySQL, Aurora)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons (Cost Mismatch)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overkill for personal development once RDS, VPC, and monitoring are included&lt;/li&gt;
&lt;li&gt;High operational cost and fixed expenses&lt;/li&gt;
&lt;li&gt;Even serverless setups accumulate costs via API Gateway and CloudWatch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;→ &lt;strong&gt;Rejected due to poor cost-performance balance&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2-5. React Native + Supabase (Direct Client Access)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;React Native connects directly to Supabase (PostgreSQL + RLS).&lt;/p&gt;

&lt;h3&gt;
  
  
  Evaluation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full RDB support&lt;/li&gt;
&lt;li&gt;Basic security via Row Level Security (RLS)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons (No Server Layer)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No API layer to implement business logic&lt;/li&gt;
&lt;li&gt;Risky secret management on the client side&lt;/li&gt;
&lt;li&gt;Insufficient as a shared backend for multiple applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;→ &lt;strong&gt;Rejected due to security and architectural limitations&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2-6. React Native + Next.js (Vercel) + Supabase
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;API built using Next.js API Routes and Vercel Edge with KV caching.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evaluation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fast responses with Edge Runtime&lt;/li&gt;
&lt;li&gt;Easy KV-based caching&lt;/li&gt;
&lt;li&gt;Seamless integration of web and API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons (Cost and Purpose Mismatch)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSR / RSC billing can quickly exhaust free tiers&lt;/li&gt;
&lt;li&gt;Limited benefit when using Next.js purely as an API&lt;/li&gt;
&lt;li&gt;Less cost-efficient for API-focused workloads compared to Workers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;→ &lt;strong&gt;Rejected due to cost efficiency concerns&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  2-7. React Native + Hono + Cloudflare Workers + Supabase (Final Choice)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Hono runs on Cloudflare Workers as the API layer.&lt;br&gt;&lt;br&gt;
Supabase (PostgreSQL + RLS) is used as the primary datastore, with Workers KV for caching.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reasons for Adoption
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Meets Security Requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JWT verification, request signing, and rate limiting at the API layer&lt;/li&gt;
&lt;li&gt;Defense in depth with Supabase RLS&lt;/li&gt;
&lt;li&gt;Cloudflare WAF can be placed in front&lt;/li&gt;
&lt;li&gt;No need to distribute Supabase anon keys to clients&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Low Cost&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Workers remain free under ~100k requests/month&lt;/li&gt;
&lt;li&gt;KV and caching reduce Supabase query volume&lt;/li&gt;
&lt;li&gt;Zero fixed operational cost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. High Scalability&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API modularization suitable for multi-app expansion&lt;/li&gt;
&lt;li&gt;Hono provides Express-like ergonomics with high performance&lt;/li&gt;
&lt;li&gt;Serverless scaling removes infrastructure concerns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. High Development Efficiency&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Workers + Hono are optimized for API-only use&lt;/li&gt;
&lt;li&gt;Simple middleware composition&lt;/li&gt;
&lt;li&gt;Smooth integration with Supabase&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;→ &lt;strong&gt;Adopted as it best satisfies both technical and non-functional requirements&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Architecture Diagram
&lt;/h2&gt;

&lt;p&gt;[ React Native App ]&lt;br&gt;
        |&lt;br&gt;
      HTTPS&lt;br&gt;
        |&lt;br&gt;
[ Cloudflare Workers (Hono API) ]&lt;br&gt;
        |&lt;br&gt;
        +--&amp;gt; JWT Verify -----&amp;gt; [ Supabase Auth ]&lt;br&gt;
        |&lt;br&gt;
        +--&amp;gt; SQL + RLS ------&amp;gt; [ Supabase PostgreSQL ]&lt;br&gt;
        |&lt;br&gt;
        +--&amp;gt; Rate Limit -----&amp;gt; [ Workers KV ]&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Comparison Table
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Security, cost, and scalability are subjective evaluations based on this project’s assumptions.&lt;/em&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Architecture&lt;/th&gt;
&lt;th&gt;RDB&lt;/th&gt;
&lt;th&gt;Security&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;th&gt;API Extensibility&lt;/th&gt;
&lt;th&gt;Overall&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Swift&lt;/td&gt;
&lt;td&gt;×&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Swift + Firebase&lt;/td&gt;
&lt;td&gt;×&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RN + Firebase&lt;/td&gt;
&lt;td&gt;×&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RN + FastAPI + AWS&lt;/td&gt;
&lt;td&gt;○&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RN + Supabase (Direct)&lt;/td&gt;
&lt;td&gt;○&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RN + Next.js + Vercel&lt;/td&gt;
&lt;td&gt;○&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Rejected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RN + Hono + Workers + Supabase&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;○&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;High&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Very Low&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;High&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Adopted&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  5. Summary
&lt;/h2&gt;

&lt;p&gt;This article compared multiple API architectures for a personal development project,&lt;br&gt;&lt;br&gt;
evaluating each option against functional and non-functional requirements.&lt;/p&gt;

&lt;p&gt;The final choice — &lt;strong&gt;React Native × Cloudflare Workers × Hono × Supabase&lt;/strong&gt; — stood out for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Strong API-level security controls&lt;/li&gt;
&lt;li&gt;Reliable RDB support with Supabase and RLS&lt;/li&gt;
&lt;li&gt;Excellent cost efficiency via Cloudflare Workers&lt;/li&gt;
&lt;li&gt;Flexible serverless scaling&lt;/li&gt;
&lt;li&gt;A structure well-suited for multi-app expansion&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>architecture</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Learning Cookie Creation and Access Through Implementation (Part 3)</title>
      <dc:creator>BysonTech</dc:creator>
      <pubDate>Sun, 28 Dec 2025 21:11:23 +0000</pubDate>
      <link>https://forem.com/bysontech_8dd1313811a8895/learning-cookie-creation-and-access-through-implementation-part-3-52on</link>
      <guid>https://forem.com/bysontech_8dd1313811a8895/learning-cookie-creation-and-access-through-implementation-part-3-52on</guid>
      <description>&lt;h2&gt;
  
  
  Understanding Cookie Issuance and Retrieval with Real Code (Java × JavaScript)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dev.to/bysontech_8dd1313811a8895/understanding-cookies-from-the-ground-up-part-1-fundamentals-and-the-critical-difference-between-2ofg"&gt;In Part 1&lt;/a&gt;, we covered what cookies are.&lt;br&gt;&lt;br&gt;
&lt;a href="https://dev.to/bysontech_8dd1313811a8895/understanding-browser-cookie-behavior-part-2-24dn"&gt;In Part 2&lt;/a&gt;, we explored when cookies are stored and sent by browsers.&lt;/p&gt;

&lt;p&gt;In Part 3, we’ll work with actual, runnable code to understand how cookies are handled in practice.&lt;/p&gt;

&lt;p&gt;We’ll cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Issuing cookies in Java (Servlet)&lt;/li&gt;
&lt;li&gt;Issuing cookies in JavaScript&lt;/li&gt;
&lt;li&gt;Reading cookies in Java (Servlet)&lt;/li&gt;
&lt;li&gt;Reading cookies in JavaScript&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  1. Issuing Cookies in Java (Servlet)
&lt;/h2&gt;

&lt;p&gt;Based on my experience, issuing cookies in Java typically follows this flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a cookie with new Cookie
&lt;/li&gt;
&lt;li&gt;Set attributes such as Path, MaxAge, HttpOnly, and Secure
&lt;/li&gt;
&lt;li&gt;Optionally set Domain
&lt;/li&gt;
&lt;li&gt;Send it using response.addCookie()
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Example: Cookie Issuance Code
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.IOException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.servlet.ServletException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.servlet.annotation.WebServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.servlet.http.Cookie&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.servlet.http.HttpServlet&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.servlet.http.HttpServletRequest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.servlet.http.HttpServletResponse&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@WebServlet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/login"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginServlet&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HttpServlet&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="nd"&gt;@Override&lt;/span&gt;
        &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;doGet&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;HttpServletResponse&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;ServletException&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

            &lt;span class="nc"&gt;Cookie&lt;/span&gt; &lt;span class="n"&gt;tokenCookie&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;Cookie&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"cookieName"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"abcd1234"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="n"&gt;tokenCookie&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setPath&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;tokenCookie&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMaxAge&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="n"&gt;tokenCookie&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setHttpOnly&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;tokenCookie&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setSecure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="n"&gt;tokenCookie&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDomain&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"localhost"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addCookie&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokenCookie&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setContentType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text/plain; charset=UTF-8"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getWriter&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cookie has been issued."&lt;/span&gt;&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;p&gt;Note:&lt;br&gt;&lt;br&gt;
In some browsers, cookies with Domain=localhost may not be stored correctly.&lt;br&gt;&lt;br&gt;
If that happens, omit the Domain attribute and rely on Path instead.&lt;/p&gt;
&lt;h3&gt;
  
  
  About Domain Configuration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Local environment&lt;br&gt;&lt;br&gt;
→ localhost or 127.0.0.1  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Production environment&lt;br&gt;&lt;br&gt;
→ Passed via environment variables&lt;br&gt;&lt;br&gt;
(e.g., System.getenv("COOKIE_DOMAIN"))&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Incorrect domain settings often cause:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cookies being stored but not sent&lt;/li&gt;
&lt;li&gt;Cookies being sent but not readable&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  2. Issuing Cookies in JavaScript
&lt;/h2&gt;

&lt;p&gt;In JavaScript, cookies are set via string assignment:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;document.cookie = "key=value; Path=/; Max-Age=seconds; attributes...";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cookieName=abcd1234; Path=/; Max-Age=86400; Secure&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Important notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HttpOnly cannot be set from JavaScript&lt;/li&gt;
&lt;li&gt;Secure cookies are sent only over HTTPS&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Reading Cookies in Java (Servlet)
&lt;/h2&gt;

&lt;p&gt;Java retrieves cookies using request.getCookies().&lt;/p&gt;

&lt;p&gt;Helper method example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;Cookie&lt;/span&gt; &lt;span class="nf"&gt;getCookie&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpServletRequest&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Cookie&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;cookies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getCookies&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cookies&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Cookie&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cookies&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&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;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&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;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="nc"&gt;Cookie&lt;/span&gt; &lt;span class="n"&gt;tokenCookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getCookie&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"cookieName"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tokenCookie&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tokenCookie&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Login token = "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;token&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;h2&gt;
  
  
  4. Reading Cookies in JavaScript
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt; &lt;span class="nx"&gt;returns&lt;/span&gt; &lt;span class="nx"&gt;all&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;single&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="nx"&gt;cookieName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;abcd1234&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;example1&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;test1&lt;/span&gt;

&lt;span class="nx"&gt;Parsing&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;example&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getCookie&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="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&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="s2"&gt;;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cookies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&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="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;cookie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;substring&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;length&lt;/span&gt; &lt;span class="o"&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="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getCookie&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cookieName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;cookieName:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HttpOnly cookies cannot be accessed from JavaScript.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Common Pitfalls in Local Development
&lt;/h2&gt;

&lt;p&gt;① Secure and &lt;a href="http://localhost" rel="noopener noreferrer"&gt;http://localhost&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Secure cookies are sent only over HTTPS.&lt;br&gt;&lt;br&gt;
Local development often uses HTTP, causing cookies not to be sent.&lt;/p&gt;

&lt;p&gt;For development, Secure=false is recommended.&lt;br&gt;&lt;br&gt;
If Secure=true is required in production, always test with HTTPS locally.&lt;/p&gt;

&lt;p&gt;② SameSite=None requires Secure=true&lt;br&gt;&lt;br&gt;
Most modern browsers require Secure when SameSite=None is used.&lt;/p&gt;

&lt;p&gt;③ Different ports mean different sites&lt;br&gt;&lt;br&gt;
localhost:3000 and localhost:8080 do not share cookies.&lt;/p&gt;

&lt;p&gt;④ Different Path or Domain means a different cookie&lt;br&gt;&lt;br&gt;
Same cookie name with different Path or Domain creates separate cookies.&lt;/p&gt;

&lt;p&gt;⑤ Browser-specific differences&lt;br&gt;&lt;br&gt;
Cookie visibility and tooling differ by browser, making cross-browser testing essential.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;Java issues cookies via new Cookie → attribute settings → response.addCookie&lt;/li&gt;
&lt;li&gt;Same name with different Path or Domain creates separate cookies&lt;/li&gt;
&lt;li&gt;JavaScript sets cookies via document.cookie&lt;/li&gt;
&lt;li&gt;HttpOnly cookies are invisible to JavaScript&lt;/li&gt;
&lt;li&gt;Local development is tricky due to Secure, SameSite, and port differences&lt;/li&gt;
&lt;li&gt;Browser behavior must always be considered&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  A Critical Security Note
&lt;/h3&gt;

&lt;p&gt;Cookies are easily manipulated on the client side:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Values can be modified&lt;/li&gt;
&lt;li&gt;Expiration can be extended&lt;/li&gt;
&lt;li&gt;Domain and Path can be changed&lt;/li&gt;
&lt;li&gt;Cookies can be deleted or added&lt;/li&gt;
&lt;li&gt;JavaScript can read/write non-HttpOnly cookies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Therefore, cookies must never be trusted as authentication proof.&lt;/p&gt;

&lt;p&gt;Dangerous designs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Storing user_id directly in cookies&lt;/li&gt;
&lt;li&gt;Treating the existence of a cookie as authentication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A proper design requires:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cookies carry signed tokens (e.g., JWT)&lt;/li&gt;
&lt;li&gt;Authentication is verified server-side&lt;/li&gt;
&lt;li&gt;Token forgery is impossible even if cookies are modified&lt;/li&gt;
&lt;li&gt;Proper use of HttpOnly, Secure, and SameSite&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>java</category>
      <category>cookie</category>
    </item>
    <item>
      <title>Understanding Browser Cookie Behavior (Part 2)</title>
      <dc:creator>BysonTech</dc:creator>
      <pubDate>Sun, 28 Dec 2025 20:51:03 +0000</pubDate>
      <link>https://forem.com/bysontech_8dd1313811a8895/understanding-browser-cookie-behavior-part-2-24dn</link>
      <guid>https://forem.com/bysontech_8dd1313811a8895/understanding-browser-cookie-behavior-part-2-24dn</guid>
      <description>&lt;h1&gt;
  
  
  Understanding Browser Cookie Behavior (Part 2)
&lt;/h1&gt;

&lt;p&gt;In Part 1, I covered &lt;a href="https://dev.to/bysontech_8dd1313811a8895/understanding-cookies-from-the-ground-up-part-1-fundamentals-and-the-critical-difference-between-2ofg"&gt;&lt;strong&gt;what cookies are and why they exist&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this second article, I’ll focus on a topic that often causes confusion in real-world development:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where browsers store cookies, and when they actually send them.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While implementing cookie issuance logic myself, I repeatedly ran into issues such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cookies not being sent as expected
&lt;/li&gt;
&lt;li&gt;Cookies not disappearing (or mysteriously remaining)
&lt;/li&gt;
&lt;li&gt;Behavior changing due to &lt;code&gt;SameSite&lt;/code&gt; differences
&lt;/li&gt;
&lt;li&gt;Different behavior across browsers
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article organizes those common points of confusion.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where Are Cookies Stored in the Browser?
&lt;/h2&gt;

&lt;p&gt;Cookies are automatically stored and managed by the browser.&lt;br&gt;&lt;br&gt;
The exact storage location differs by browser, but the concept is the same.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chrome (Chromium-based browsers)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Stored in a local SQLite database (e.g., a &lt;code&gt;Cookies&lt;/code&gt; file)&lt;/li&gt;
&lt;li&gt;Viewable via DevTools: &lt;strong&gt;Application &amp;gt; Cookies&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Safari (macOS / iOS)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Managed internally by WebKit&lt;/li&gt;
&lt;li&gt;Often not accessible as user-visible files&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Firefox
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Stored in &lt;code&gt;cookies.sqlite&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Accessible via DevTools under the &lt;strong&gt;Storage&lt;/strong&gt; tab&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In all cases, developers never interact with these files directly—the browser handles everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Are Cookies Sent?
&lt;/h2&gt;

&lt;p&gt;Cookies are only sent when &lt;strong&gt;all required conditions are satisfied&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
If even one condition fails, the browser will not include the cookie.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The request domain matches the &lt;code&gt;Domain&lt;/code&gt; attribute
&lt;/li&gt;
&lt;li&gt;The request path matches the &lt;code&gt;Path&lt;/code&gt; attribute
&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;Secure&lt;/code&gt; is set, the request uses HTTPS
&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;SameSite&lt;/code&gt; condition is satisfied
&lt;/li&gt;
&lt;li&gt;The cookie has not expired
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If any of these are misconfigured, cookies may silently fail to be sent.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cookie Attributes and Their Behavior
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Domain
&lt;/h3&gt;

&lt;p&gt;Example:&lt;br&gt;&lt;br&gt;
&lt;code&gt;Set-Cookie: token=abc; Domain=example.com;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This cookie will be sent to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;example.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;www.example.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you specify &lt;code&gt;Domain=www.example.com&lt;/code&gt;, the cookie is only sent to that exact host.&lt;/p&gt;

&lt;p&gt;If the &lt;code&gt;Domain&lt;/code&gt; attribute is omitted, the cookie becomes a &lt;strong&gt;host-only cookie&lt;/strong&gt;,&lt;br&gt;&lt;br&gt;
meaning it is sent only to the issuing domain and not to subdomains.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Path
&lt;/h3&gt;

&lt;p&gt;Example:&lt;br&gt;&lt;br&gt;
&lt;code&gt;Set-Cookie: token=abc; Path=/app;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The cookie is sent only for requests under &lt;code&gt;/app&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;Path=/&lt;/code&gt; causes the cookie to be sent with all requests to the domain.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Secure
&lt;/h3&gt;

&lt;p&gt;Cookies with the &lt;code&gt;Secure&lt;/code&gt; attribute are &lt;strong&gt;only sent over HTTPS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;https://example.com&lt;/code&gt; → sent
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;http://localhost&lt;/code&gt; → not sent
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a common pitfall in local development.&lt;br&gt;&lt;br&gt;
I personally lost time debugging issues caused by not fully understanding this behavior.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. HttpOnly
&lt;/h3&gt;

&lt;p&gt;Cookies with &lt;code&gt;HttpOnly&lt;/code&gt; &lt;strong&gt;cannot be accessed from JavaScript&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because of this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;HttpOnly&lt;/code&gt; cookies cannot be set via JavaScript&lt;/li&gt;
&lt;li&gt;They must be set using &lt;code&gt;Set-Cookie&lt;/code&gt; on the server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;br&gt;&lt;br&gt;
&lt;code&gt;document.cookie&lt;/code&gt;&lt;br&gt;&lt;br&gt;
→ &lt;code&gt;HttpOnly&lt;/code&gt; cookies will not appear&lt;/p&gt;

&lt;p&gt;This attribute is critical for security, especially as a defense against XSS.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. SameSite
&lt;/h3&gt;

&lt;p&gt;One of the most impactful cookie attributes today.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;SameSite=Lax&lt;/code&gt; (default)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SameSite=None&lt;/code&gt; (allows cross-site requests, but requires &lt;code&gt;Secure&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SameSite=Strict&lt;/code&gt; (sent only for same-site requests)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Authentication flows and integrations with external services often fail because cookies are blocked by &lt;code&gt;SameSite&lt;/code&gt; rules.&lt;/p&gt;




&lt;h2&gt;
  
  
  Differences in Browser Behavior
&lt;/h2&gt;

&lt;p&gt;Due to historical reasons and security policies, cookie behavior differs slightly between browsers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chrome
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Strict adherence to &lt;code&gt;SameSite&lt;/code&gt; specifications&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SameSite=None&lt;/code&gt; requires &lt;code&gt;Secure&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Safari (including iOS)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Strongly affected by &lt;strong&gt;ITP (Intelligent Tracking Prevention)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;3rd-party cookies are deleted very quickly&lt;/li&gt;
&lt;li&gt;Even 1st-party cookies may be deleted if the user does not revisit within 7 days&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many cases of “login sessions suddenly expiring” or unstable external integrations are caused by ITP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Firefox
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Generally close to the specification&lt;/li&gt;
&lt;li&gt;Behavior may differ in private browsing mode&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because of these differences, testing across multiple browsers is essential.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Reasons Cookies “Remain” or “Disappear”
&lt;/h2&gt;

&lt;p&gt;Typical causes encountered in development include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cookies with different &lt;code&gt;Path&lt;/code&gt; values existing simultaneously
&lt;/li&gt;
&lt;li&gt;Multiple cookies created due to different &lt;code&gt;Domain&lt;/code&gt; settings
&lt;/li&gt;
&lt;li&gt;Cookies blocked by &lt;code&gt;SameSite&lt;/code&gt; in cross-site requests
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Secure&lt;/code&gt; cookies not sent over HTTP in local environments
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HttpOnly&lt;/code&gt; cookies not visible in JavaScript, causing confusion
&lt;/li&gt;
&lt;li&gt;Automatic deletion by Safari’s ITP
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since I previously paid little attention to browser-level behavior, it took time to determine whether issues were caused by my implementation or by browser rules.&lt;/p&gt;

&lt;p&gt;Cookies often fail due to overlapping conditions, so debugging requires checking them one by one.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cookies are stored internally in the browser (often using SQLite)&lt;/li&gt;
&lt;li&gt;Cookie transmission depends on &lt;code&gt;Domain&lt;/code&gt;, &lt;code&gt;Path&lt;/code&gt;, &lt;code&gt;Secure&lt;/code&gt;, &lt;code&gt;SameSite&lt;/code&gt;, and &lt;code&gt;HttpOnly&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SameSite&lt;/code&gt; is a critical modern attribute that must be understood&lt;/li&gt;
&lt;li&gt;Safari’s ITP has a strong impact on cookie behavior&lt;/li&gt;
&lt;li&gt;Issues with cookies persisting or disappearing are usually due to configuration or browser differences&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Part 3 Preview
&lt;/h2&gt;

&lt;p&gt;In the next article, I’ll walk through real code examples, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Issuing cookies on the server side (Java)&lt;/li&gt;
&lt;li&gt;Manipulating cookies with JavaScript&lt;/li&gt;
&lt;li&gt;Common pitfalls in local development&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Original Japanese article:&lt;br&gt;&lt;br&gt;
&lt;a href="https://zenn.dev/bysontech/articles/68c9e472adb403" rel="noopener noreferrer"&gt;https://zenn.dev/bysontech/articles/68c9e472adb403&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>cookie</category>
      <category>architecture</category>
    </item>
    <item>
      <title>What Is a Cookie? A Clear Introduction from the Basics (Part 1)</title>
      <dc:creator>BysonTech</dc:creator>
      <pubDate>Sun, 28 Dec 2025 08:03:03 +0000</pubDate>
      <link>https://forem.com/bysontech_8dd1313811a8895/understanding-cookies-from-the-ground-up-part-1-fundamentals-and-the-critical-difference-between-2ofg</link>
      <guid>https://forem.com/bysontech_8dd1313811a8895/understanding-cookies-from-the-ground-up-part-1-fundamentals-and-the-critical-difference-between-2ofg</guid>
      <description>&lt;h1&gt;
  
  
  What Is a Cookie? A Clear Introduction from the Basics (Part 1)
&lt;/h1&gt;

&lt;p&gt;A while ago, I worked on a project that introduced &lt;strong&gt;Risk-Based Authentication (RBA)&lt;/strong&gt; — the mechanism that detects suspicious logins (such as foreign access or unusual behavior) and requires additional verification.&lt;/p&gt;

&lt;p&gt;Before we could even design the authentication logic, we ran into a prerequisite concept: &lt;strong&gt;cookies&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To be honest, even after working with Java and React, I was in the familiar situation of&lt;br&gt;&lt;br&gt;
“I kind of know what cookies are, but I can’t explain them clearly.”&lt;br&gt;&lt;br&gt;
No one on the team had a solid explanation either, so I decided to start by revisiting &lt;strong&gt;how cookies actually work from the ground up&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This article is for people who are at the same stage I was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What exactly is a cookie?&lt;/li&gt;
&lt;li&gt;Why do we need it in the first place?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ll focus only on the fundamentals.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is a Cookie?
&lt;/h2&gt;

&lt;p&gt;In short, a cookie is&lt;br&gt;&lt;br&gt;
&lt;strong&gt;a small piece of data that a website stores in your browser&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When a browser sends an HTTP request to a server, cookies are automatically included in the request.&lt;br&gt;&lt;br&gt;
This allows the server to continuously recognize things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether this user has visited before
&lt;/li&gt;
&lt;li&gt;Whether the user is authenticated
&lt;/li&gt;
&lt;li&gt;Which preferences or settings are in use
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HTTP itself is &lt;strong&gt;stateless&lt;/strong&gt; by design — it does not remember past requests.&lt;br&gt;&lt;br&gt;
Cookies are one of the primary mechanisms used to fill this gap.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Are Cookies Necessary?
&lt;/h2&gt;

&lt;p&gt;Cookies serve many purposes, but their core roles can be summarized into two main ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. User Identification
&lt;/h3&gt;

&lt;p&gt;To distinguish authenticated users, cookies often store a &lt;strong&gt;session ID&lt;/strong&gt; or a &lt;strong&gt;token identifier&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Without cookies, login information would be lost on every page transition.&lt;br&gt;&lt;br&gt;
The reason users can stay logged in is that cookies are automatically sent with each request.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Persisting User Preferences
&lt;/h3&gt;

&lt;p&gt;Cookies are also used to remember user-specific settings such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dark mode
&lt;/li&gt;
&lt;li&gt;Language preferences
&lt;/li&gt;
&lt;li&gt;Partially completed forms
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In other words, cookies exist to &lt;strong&gt;maintain state&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
In the project I worked on, they were mainly used for the first purpose: authentication.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Difference Between 1st-Party and 3rd-Party Cookies
&lt;/h2&gt;

&lt;p&gt;When learning about cookies, you will almost always encounter the distinction between&lt;br&gt;&lt;br&gt;
&lt;strong&gt;1st-party cookies&lt;/strong&gt; and &lt;strong&gt;3rd-party cookies&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The difference is based on &lt;strong&gt;which domain issued the cookie&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1st-Party Cookies
&lt;/h3&gt;

&lt;p&gt;Cookies issued by the site you are currently visiting.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;&lt;br&gt;
If you are browsing &lt;code&gt;example.com&lt;/code&gt; and its server returns a &lt;code&gt;Set-Cookie&lt;/code&gt; header, that cookie is a 1st-party cookie.&lt;/p&gt;

&lt;p&gt;Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Used for authentication and session management
&lt;/li&gt;
&lt;li&gt;Few restrictions in modern browsers
&lt;/li&gt;
&lt;li&gt;Essential for basic web application behavior
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3rd-Party Cookies
&lt;/h3&gt;

&lt;p&gt;Cookies issued by a domain different from the one you are visiting.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;&lt;br&gt;
An advertising network like &lt;code&gt;ad.example.net&lt;/code&gt; issuing its own cookie inside a page you’re viewing.&lt;/p&gt;

&lt;p&gt;Characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traditionally used for ads and cross-site tracking
&lt;/li&gt;
&lt;li&gt;Strongly restricted by most modern browsers
&lt;/li&gt;
&lt;li&gt;Being phased out entirely (Chrome included, gradually)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why This Distinction Matters
&lt;/h2&gt;

&lt;p&gt;In risk-based authentication, decisions are made based on signals such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which browser the request comes from
&lt;/li&gt;
&lt;li&gt;Whether the same device has authenticated before
&lt;/li&gt;
&lt;li&gt;When and where a cookie was issued
&lt;/li&gt;
&lt;li&gt;Whether consistency is maintained within the same site
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cookie data is especially important for detecting suspicious behavior.&lt;br&gt;&lt;br&gt;
For this reason, systems are typically designed to rely on &lt;strong&gt;safe, controllable 1st-party cookies&lt;/strong&gt;, while avoiding unnecessary dependence on 3rd-party cookies.&lt;/p&gt;

&lt;p&gt;Understanding this distinction is a prerequisite for making sound design and implementation decisions later.&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cookies are small pieces of data stored in the browser
&lt;/li&gt;
&lt;li&gt;HTTP is stateless, so cookies enable state management
&lt;/li&gt;
&lt;li&gt;Cookies are widely used for authentication, preferences, and user identification
&lt;/li&gt;
&lt;li&gt;1st-party cookies are issued by the site itself
&lt;/li&gt;
&lt;li&gt;3rd-party cookies are issued by external domains and are heavily restricted today
&lt;/li&gt;
&lt;li&gt;Proper cookie handling is fundamental to risk-based authentication
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What’s Next (Part 2)
&lt;/h2&gt;

&lt;p&gt;In the next article, I’ll dive into &lt;strong&gt;how browsers actually handle cookies&lt;/strong&gt;, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where browsers store cookies
&lt;/li&gt;
&lt;li&gt;When cookies are sent with requests
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SameSite&lt;/code&gt;, &lt;code&gt;Secure&lt;/code&gt;, and &lt;code&gt;HttpOnly&lt;/code&gt; attributes
&lt;/li&gt;
&lt;li&gt;Differences between Chrome, Safari, and Edge
&lt;/li&gt;
&lt;li&gt;How to inspect cookies using developer tools
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ll focus on the points that tend to cause confusion in real-world development.&lt;/p&gt;

&lt;p&gt;Original Japanese article:&lt;br&gt;&lt;br&gt;
&lt;a href="https://zenn.dev/bysontech/articles/dd7cfb2c9faf57t" rel="noopener noreferrer"&gt;https://zenn.dev/bysontech/articles/dd7cfb2c9faf57t&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>beginners</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
