{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Jubayer Al Mamun - Writing",
  "home_page_url": "https://jubayeramb.com/",
  "feed_url": "https://jubayeramb.com/feed.json",
  "description": "Notes on JavaScript, TypeScript, Astro, and the occasional reflection by Jubayer Al Mamun.",
  "icon": "https://jubayeramb.com/icon-512.png",
  "favicon": "https://jubayeramb.com/icon-192.png",
  "language": "en-US",
  "authors": [
    {
      "name": "Jubayer Al Mamun",
      "url": "https://jubayeramb.com/about/"
    }
  ],
  "items": [
    {
      "id": "https://jubayeramb.com/writings/jev-system-one-model-vs-llms/",
      "url": "https://jubayeramb.com/writings/jev-system-one-model-vs-llms/",
      "title": "Jev and System One Models: When You Need a Decision, Not a Chat",
      "summary": "What TypeSafe AI's Jev is, how a System One Model differs from an LLM, what the workflow benchmarks actually show, and when it makes sense to reach for one.",
      "content_html": "<p>Models have been good at chat for years.\nSo why is most automation in production still a pile of <code>if</code> statements?</p>\n<p>That is the question TypeSafe AI opened their launch post with, and it is a fair one.\nOn September 15, 2026, after two years in stealth, they released <strong>Jev</strong>, the first model in a class they call <strong>System One Models</strong>.\nIt does not write text.\nIt makes decisions your code can use directly.</p>\n<p>I have not had early access yet, so everything below comes from TypeSafe’s <a href=\"https://typesafe.ai/blog/introducing-system-one-models-and-jev\">launch post</a>, their <a href=\"https://docs.typesafe.ai/\">docs</a>, and their <a href=\"https://evals.typesafe.ai/\">published workflow evals</a>.\nWhere their numbers are strong, I say so.\nWhere they are weaker than the headline, I say that too.</p>\n<h2 id=\"the-30-second-answer\"><a class=\"heading-link\" href=\"#the-30-second-answer\">The 30-second answer</a></h2>\n<p>An LLM writes a string, and your code has to parse it, validate it, and hope it did not go off the rails.\nJev picks from answers you define in advance, and returns a probability for each one.</p>\n<p>If the thing you need back is a sentence, use an LLM.\nIf the thing you need back is a branch in your code, that is what Jev is for.</p>\n<h2 id=\"what-is-jev\"><a class=\"heading-link\" href=\"#what-is-jev\">What is Jev?</a></h2>\n<p>Jev comes from TypeSafe AI, a San Francisco lab founded by Diogo Almeida, who worked at OpenAI on the instruction-following research that became ChatGPT.\nTypeSafe describes Jev as “a frontier-intelligence function call: unstructured state in, typed probabilistic decisions out.”</p>\n<p>The names are borrowed.\n“System One” comes from Daniel Kahneman’s <a href=\"https://www.penguinrandomhouse.com/books/89308/thinking-fast-and-slow-by-daniel-kahneman/\">Thinking, Fast and Slow</a>: fast, intuitive System 1 judgment versus slow, deliberate System 2 reasoning.\n“Jev” is after William Stanley Jevons, who noticed that cheaper coal led to more coal use, not less.\nTheir bet is the same for intelligence: make a decision cost a fraction of a cent and people will put one everywhere.</p>\n<h3 id=\"how-it-differs-from-an-llm\"><a class=\"heading-link\" href=\"#how-it-differs-from-an-llm\">How it differs from an LLM</a></h3>\n<p>TypeSafe changed three things at once: the architecture, the sampler, and the training method.\nHere is their own comparison, condensed:</p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th></th><th>LLMs</th><th>Jev</th></tr></thead><tbody><tr><td>Trained for</td><td>Human preference (RLHF) or verifiable rewards (RLVR)</td><td>Calibrated decisions (RLCD, their new method)</td></tr><tr><td>Output</td><td>A string, parsed and validated by your code</td><td>Typed values, only from options you defined</td></tr><tr><td>Sampling</td><td>One token at a time, each depending on the last</td><td>All answers in one parallel pass</td></tr><tr><td>Confidence</td><td>Overconfident and inconsistent, even when asked</td><td>A probability on every answer</td></tr><tr><td>Speed</td><td>3 to 329 s end to end for frontier models</td><td>70 to 500 ms end to end</td></tr><tr><td>Price</td><td>$0.20 to $10 per million input tokens, output ~5x more</td><td>$0.042 per million input tokens, output free</td></tr></tbody></table>\n<p>The sampling row is the one that explains the rest.\nAn LLM answering three questions has to write them out, token by token, in order.\nJev scores every option for every question at the same time.</p>\n<figure>\n<video src=\"https://jubayeramb.com/assets/images/blog/jev-system-one-model/sampling.mp4\" poster=\"/assets/images/blog/jev-system-one-model/sampling-poster.png\" width=\"1600\" height=\"900\" autoplay muted loop playsinline preload=\"metadata\" aria-label=\"Side by side animation. On the left an LLM types out a JSON answer one token at a time. On the right Jev fills in all three typed answers at once, each with a probability bar.\"></video>\n<figcaption>An 8 second loop. Both sides start empty: Jev fills in all three answers at once while the LLM is still typing its first field.</figcaption>\n</figure>\n<p>Giving up text is the whole trade.\nJev cannot write you an email.\nIn exchange it cannot return a department that does not exist, a score of “high-ish”, or a refusal where a boolean should be.</p>\n<h2 id=\"what-a-call-looks-like\"><a class=\"heading-link\" href=\"#what-a-call-looks-like\">What a call looks like</a></h2>\n<p>There are three question types, and every answer comes back typed:</p>\n<ul>\n<li><strong>Choice.</strong> One option from a set you define. Returns the choice, a probability for each option, and a confidence.</li>\n<li><strong>Score.</strong> A level on a scale you describe. Returns a score, the probabilities per level, and a confidence.</li>\n<li><strong>Noul.</strong> A yes or no. Returns the probability that it is true.</li>\n</ul>\n<p>Here is the support ticket example from their quickstart, written with their TypeScript SDK, <a href=\"https://www.npmjs.com/package/@typesafe-ai/sdk\"><code>@typesafe-ai/sdk</code></a>.\nOne ticket, three questions, one call:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"ts\"><code><span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { choice, noul, score, TypeSafeClient } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">from</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"@typesafe-ai/sdk\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">const</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> client</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> =</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> new</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> TypeSafeClient</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(); </span><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">// reads TYPESAFE_API_KEY</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">const</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> ticket</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> =</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">  \"Hi, I've been trying to connect my Stripe account for 3 days and the integration keeps failing. I'm losing sales. Please help ASAP.\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">const</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">answers</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> await</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> client.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">systemOne</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  state: ticket,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  questions: {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    department: </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">choice</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Which team should handle this\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      billing: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Payment or subscription issues\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      technical: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Bugs or integration problems\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      sales: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Pricing or account questions\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    frustration: </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">score</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"How frustrated the customer appears\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, [</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">      \"Calm, just stating facts\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">      \"Frustrated but civil\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">      \"Very angry, strong language\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    ]),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    is_urgent: </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">noul</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"The message conveys urgency or time-sensitivity\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  },</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">});</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">answers.department.choice; </span><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">// \"billing\" | \"technical\" | \"sales\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">answers.frustration.score; </span><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">// number, 0 to 2</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">answers.is_urgent.noul; </span><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">// number, probability of yes</span></span></code></pre>\n<p>The SDK infers each answer’s type from its question, so <code>answers.department.choice</code> is the union of your three labels, not a <code>string</code>.</p>\n<p>And the answers that come back (trimmed):</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"json\"><code><span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">{</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">  \"department\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    \"choice\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"technical\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    \"confidence\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0.78</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">    \"probabilities\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: { </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">\"technical\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0.85</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">\"billing\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0.15</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">\"sales\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0.0</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  },</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">  \"frustration\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: { </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">\"score\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">1.0</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">\"confidence\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">1.0</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> },</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">  \"is_urgent\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: { </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">\"noul\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">1.0</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<p><img src=\"https://jubayeramb.com/assets/images/blog/jev-system-one-model/how-a-call-works.png\" alt=\"One Jev call, left to right. A support ticket and three typed questions go into Jev. Out come typed answers with probabilities: technical at 0.85, frustration level 1, urgent at 1.0. Your code then gates on confidence: act, confirm, or route to a person.\" width=\"1600\" height=\"900\" loading=\"lazy\" decoding=\"async\"></p>\n<p>Notice what is missing.\nNo prompt asking for JSON, no parser, no retry when the model wraps the JSON in a sentence.\nThe shape of the answer is the shape of the question.</p>\n<p>The docs are also clear about what makes a good question.\nAsk for a judgment a knowledgeable person makes in a second, like “Does this message convey urgency?”\nDo not ask it to “analyze this message and determine the best course of action.”\nIf a decision depends on several factors, ask about each one separately and combine them in code, so a change in priorities is a change in weights, not a rewritten prompt.</p>\n<h2 id=\"confidence-is-the-real-feature\"><a class=\"heading-link\" href=\"#confidence-is-the-real-feature\">Confidence is the real feature</a></h2>\n<p>This line from the launch post is the best argument for the whole idea:</p>\n<blockquote>\n<p>If a model can do a task 95% of the time but doesn’t say when it’s in the 5%, it can’t automate that task.</p>\n</blockquote>\n<p>Every Choice and Score answer comes with a confidence between 0 and 1, derived from how peaked the probabilities are.\nThe docs suggest three paths: act on high confidence, confirm on medium, hand off on low.\nAnd the threshold should follow the stakes, not be one number for the whole system:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"ts\"><code><span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">const</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">answers</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> await</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> client.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">systemOne</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">({</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  state: userMessage,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  questions: {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    action: </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">choice</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"What is the user trying to do?\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      check_balance: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"View account balance\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      approve_transfer: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Approve the pending withdrawal request\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      support: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Get help with an issue\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  },</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">});</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">const</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">action</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> answers;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (action.confidence </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">&#x3C;</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.5</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  routeToHuman</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(userMessage); </span><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">// genuinely unsure, don't guess</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">} </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">else</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (action.choice </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">===</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"check_balance\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  showBalance</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(accountId); </span><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">// low stakes, a wrong screen is recoverable</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">} </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">else</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (action.choice </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">===</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"approve_transfer\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">  if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (action.confidence </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">></span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 0.9</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">    confirmThenExecute</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(accountId); </span><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">// high stakes, high confidence</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">else</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">    askUserToConfirm</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(accountId); </span><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">// high stakes, verify first</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<p>You can ask an LLM for a confidence score too, but you get a number it wrote, not a number it measured.\nThat difference is what lets you put a model somewhere nobody is watching.</p>\n<h2 id=\"the-workflow-benchmark\"><a class=\"heading-link\" href=\"#the-workflow-benchmark\">The workflow benchmark</a></h2>\n<p>This is the part I spent the most time on, because the headline on their homepage is “193.6x faster, 444.6x cheaper” and that is the kind of number that deserves a closer look.</p>\n<h3 id=\"how-they-test\"><a class=\"heading-link\" href=\"#how-they-test\">How they test</a></h3>\n<p>TypeSafe built a new kind of eval for AI inside code.\nThey take a written business policy and turn it into a workflow: every sentence becomes either a narrow question for the model (a Noul, Choice, or Score) or a rule in code.\nEvery model gets the exact same workflow.\nThe reference answers are the average of two of the largest and most expensive models available, GPT-6 Astra and Claude Fable 5.1, both at high thinking.\nSo “accuracy” here means agreement with those two models, not with human labels.</p>\n<p>There are four published workflows:</p>\n<ul>\n<li><strong>Security incidents.</strong> An alert fires on a machine. Close it, pass it to an analyst, or contain it now.</li>\n<li><strong>Agent trace observability.</strong> A support agent finished a run. Does a person need to look at it, and how soon?</li>\n<li><strong>Invoice processing.</strong> A bill arrives with the order and the delivery record. Pay, hold, or send back.</li>\n<li><strong>Customer service.</strong> A customer writes in. What should the assistant say and do next?</li>\n</ul>\n<h3 id=\"the-results\"><a class=\"heading-link\" href=\"#the-results\">The results</a></h3>\n<p>Averaged across the four, with every model running the same workflow:</p>\n<p><img src=\"https://jubayeramb.com/assets/images/blog/jev-system-one-model/benchmark-frontier.png\" alt=\"Scatter chart of mean accuracy against cost per case on a log scale. Jev sits far to the left at 67.8% and $0.0004. Sonnet 5 matches its 67.8% at $0.1174. Sol at 74.1% and Opus 5 at 73.1% are the most accurate, at $0.0836 and $0.1761.\" width=\"1600\" height=\"900\" loading=\"lazy\" decoding=\"async\"></p>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<table><thead><tr><th>Model</th><th>Accuracy</th><th>Cost per case</th><th>Time per case</th></tr></thead><tbody><tr><td><strong>Jev</strong></td><td><strong>67.8%</strong></td><td><strong>$0.0004</strong></td><td><strong>0.4 s</strong></td></tr><tr><td>Sol (OpenAI)</td><td>74.1%</td><td>$0.0836</td><td>23.3 s</td></tr><tr><td>Opus 5 (Anthropic)</td><td>73.1%</td><td>$0.1761</td><td>37.8 s</td></tr><tr><td>Terra (OpenAI)</td><td>67.9%</td><td>$0.0304</td><td>10.1 s</td></tr><tr><td>Sonnet 5 (Anthropic)</td><td>67.8%</td><td>$0.1174</td><td>78.1 s</td></tr><tr><td>Luna (OpenAI)</td><td>66.8%</td><td>$0.0033</td><td>12.9 s</td></tr><tr><td>DeepSeek V4 Pro</td><td>65.5%</td><td>$0.0413</td><td>86.5 s</td></tr><tr><td>DeepSeek V4 Flash</td><td>64.4%</td><td>$0.0059</td><td>51.9 s</td></tr><tr><td>Haiku 4.5 (Anthropic)</td><td>53.6%</td><td>$0.0195</td><td>12.5 s</td></tr></tbody></table>\n<p>A few things stand out.</p>\n<p><strong>Jev is not the most accurate model here.</strong>\nSol and Opus 5 agree with the reference about 5 to 6 points more often.\nWhat Jev does is sit at the same level as Sonnet 5 and Terra, at a tiny fraction of the cost and time.</p>\n<p><strong>The size of the gap depends on who you compare against.</strong>\nAgainst Sonnet 5 at the same accuracy, Jev is roughly 290x cheaper and 195x faster per case.\nAgainst Terra, it is roughly 75x cheaper and 25x faster.\nAgainst Luna, the cheapest model in the same accuracy range, it is roughly 8x cheaper and 30x faster.\nAll real gains, but closer to one or two orders of magnitude than the homepage suggests.\nTypeSafe says as much themselves: they expect their headline numbers “are on the higher end of real world gains.”</p>\n<p><strong>It is not even across tasks.</strong></p>\n<p><img src=\"https://jubayeramb.com/assets/images/blog/jev-system-one-model/per-workflow.png\" alt=\"Paired bars for each workflow comparing Jev with the best LLM. Customer service: Jev 76.0%, Sol 78.3%. Agent trace observability: Jev 71.6%, Sol 76.6%. Security incidents: Jev 61.7%, Opus 5 66.2%. Invoice processing: Jev 61.8%, Sol 79.1%.\" width=\"1600\" height=\"900\" loading=\"lazy\" decoding=\"async\"></p>\n<p>On customer service, Jev is within about 2 points of the best model.\nOn invoice processing, it is about 17 points behind.\nMatching an invoice against an order and a delivery record looks like the kind of careful cross-checking that still wants a slower model.\nA snap judgment on a customer message does not.</p>\n<h3 id=\"the-finding-that-applies-to-every-model\"><a class=\"heading-link\" href=\"#the-finding-that-applies-to-every-model\">The finding that applies to every model</a></h3>\n<p>The eval also ran every LLM a second way: the same policy pasted in as one big prompt, no workflow.\nEvery model did better in the workflow, and was cheaper and faster doing it.\nHaiku 4.5 went from 18.1% as a prompt to 53.6% as a workflow.\nOpus 5 went from 64.8% to 73.1% while costing about half as much.</p>\n<p>That holds whether or not you ever use Jev.\nBreaking a decision into narrow questions and letting code do the logic beats asking any model to do it all in one shot.</p>\n<h3 id=\"read-the-fine-print\"><a class=\"heading-link\" href=\"#read-the-fine-print\">Read the fine print</a></h3>\n<p>TypeSafe is unusually upfront about the limits of their own evidence, and it is worth repeating:</p>\n<ul>\n<li>These are vendor-run evals, and the workflows were written by people on TypeSafe’s model team. They say the tasks were not picked to flatter Jev and are not in its training data, but bias could exist.</li>\n<li>The reference labels come from OpenAI and Anthropic models, which they note likely favors those providers.</li>\n<li>Speed was measured from their laptops on the US West Coast, where the service runs. From Dhaka, add the round trip.</li>\n<li>They cannot yet prove the pricing is not subsidized, and say time will have to show that.</li>\n<li>The “0% hallucination” claim is about type errors, and it is true by construction, not measured. Jev cannot return a value outside your schema. It can still return the wrong value.</li>\n</ul>\n<h2 id=\"when-to-reach-for-jev\"><a class=\"heading-link\" href=\"#when-to-reach-for-jev\">When to reach for Jev</a></h2>\n<ul>\n<li><strong>Smart <code>if</code> statements.</strong> Classify, route, score, extract, or branch where hand-written rules are too brittle.</li>\n<li><strong>Guardrails and verification.</strong> Score or flag LLM outputs, reasoning traces, or prompts, including jailbreak detection, for a fraction of what a second LLM pass costs.</li>\n<li><strong>Running over a lot of data.</strong> Tagging a million rows is a different conversation at $0.0004 a case than at $0.10.</li>\n<li><strong>Real time.</strong> At 70 to 500 ms, a model call can sit inside a UI interaction or a game loop. Their Doom demo makes about 10 decisions a second for roughly $7 an hour.</li>\n</ul>\n<h2 id=\"when-to-stay-with-an-llm\"><a class=\"heading-link\" href=\"#when-to-stay-with-an-llm\">When to stay with an LLM</a></h2>\n<ul>\n<li><strong>The output is text.</strong> Chat, drafts, summaries, code. Jev gives all of that up by design.</li>\n<li><strong>The task needs real reasoning.</strong> Multi-step work, or cross-checking several documents, like the invoice workflow above.</li>\n<li><strong>You cannot list the options.</strong> Jev handles up to 255 choices directly, and splits larger sets into a two-stage score-then-choose step. Open-ended answers are not its shape.</li>\n<li><strong>Big inputs.</strong> The Cloudflare listing shows a 32,000 token context window.</li>\n</ul>\n<p>Most real systems will use both.\nThe LLM talks to the person.\nJev makes the calls in the code around it.</p>\n<p>At work I built a chat agent that quotes prices, books pickups, and captures leads.\nThe conversation is an LLM’s job.\nBut the questions behind it, like “is this person asking to book?”, “is this a complaint?”, or “does this need a human?”, are exactly the one-second judgments Jev is built for.\nThat is where I would try it first.</p>\n<h2 id=\"the-short-rule-i-use\"><a class=\"heading-link\" href=\"#the-short-rule-i-use\">The short rule I use</a></h2>\n<p>When I am wiring an AI step into code, I ask one question.\n<em>Do I need a sentence, or a decision?</em></p>\n<p>A sentence is an LLM.\nA decision is a System One Model.</p>\n<p>Jev is in early access through the <a href=\"https://console.typesafe.ai/\">TypeSafe console</a>, and it is also listed on <a href=\"https://developers.cloudflare.com/ai/models/typesafe/jev/\">Cloudflare’s model catalog</a>.\nIf you have tried it and your numbers look different from theirs, I would love to hear about it.\nThe fastest ways to reach me are on the <a href=\"https://jubayeramb.com/contact\">contact page</a>.</p>",
      "date_published": "2026-09-22T00:00:00.000Z",
      "tags": [
        "Technical",
        "AI",
        "LLM",
        "Agents",
        "Automation"
      ]
    },
    {
      "id": "https://jubayeramb.com/writings/ai-skills-vs-mcp-when-to-use-what/",
      "url": "https://jubayeramb.com/writings/ai-skills-vs-mcp-when-to-use-what/",
      "title": "AI Skills vs MCP: When to Use What",
      "summary": "A practical guide to AI agent skills and the Model Context Protocol. What each one is, what it costs you in context, and how to pick the right one without overthinking it.",
      "content_html": "<p>If you build with agents, you have probably been asked the same question a dozen times this year. Should I write a Skill for this, or wrap it in an MCP server? Both extend what an agent can do. Both come from the same Anthropic playbook. Both have loud fan bases on the timeline.</p>\n<p>The line between them is actually pretty crisp once you see it. This is the short version, with examples, so you can stop guessing.</p>\n<h2 id=\"the-30-second-answer\"><a class=\"heading-link\" href=\"#the-30-second-answer\">The 30-second answer</a></h2>\n<p>Skills teach your agent <strong>how</strong> to do a task well. MCP gives your agent <strong>access</strong> to systems it would not otherwise reach. That is the whole frame.</p>\n<p>If the gap you are trying to close is “the model does not know our house style,” that is a Skill. If the gap is “the model cannot see our Drive, Postgres, or Linear,” that is MCP.</p>\n<p><img src=\"https://jubayeramb.com/assets/images/blog/ai-skills-vs-mcp/at-a-glance.png\" alt=\"Skills vs MCP at a glance. Two cards side by side. Skills: teach the how, lives in files, loads progressively, runs locally. MCP: reach the world, lives behind a server, loads all tool schemas upfront, runs across the wire.\" width=\"1600\" height=\"900\" loading=\"lazy\" decoding=\"async\"></p>\n<p>That single sentence covers most of the decisions you will make. The rest of this post is the <em>why</em> behind it, and the edge cases where the answer is “use both.”</p>\n<h2 id=\"what-are-ai-skills-really\"><a class=\"heading-link\" href=\"#what-are-ai-skills-really\">What are AI Skills, really?</a></h2>\n<p>A Skill is a folder. Inside that folder is a <code>SKILL.md</code> file with some YAML metadata at the top, instructions in the body, and any extra files the agent might need. Templates, scripts, examples, a checklist.</p>\n<p>A tiny one looks like this:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>pr-review/</span></span>\n<span class=\"line\"><span>  SKILL.md</span></span>\n<span class=\"line\"><span>  checklist.md</span></span>\n<span class=\"line\"><span>  examples/</span></span>\n<span class=\"line\"><span>    good-pr.md</span></span>\n<span class=\"line\"><span>    bad-pr.md</span></span></code></pre>\n<p>The <code>SKILL.md</code> itself starts with a frontmatter block the agent reads at startup:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"md\"><code><span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold\">---</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">name: pr-review</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">description: Use when reviewing a pull request. Walks the checklist,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  flags risky patterns, and writes the review comment.</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold\">---</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold\">## How to review</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">1.</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> Read the diff top to bottom.</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">2.</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> Run through </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">`checklist.md`</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">3.</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> For anything risky, point to a line and quote the file path.</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">4.</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> Use the tone in </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">`examples/good-pr.md`</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span></span></code></pre>\n<p>The smart part is what happens at runtime. The agent does <strong>not</strong> load every Skill into context. It loads only the metadata, which is a hundred tokens or so per Skill. When the user actually asks for a pull request review, the agent reads the body. If the body points to <code>checklist.md</code>, the agent reads that too. If it never needs <code>bad-pr.md</code>, it never opens it.</p>\n<p>This is called progressive disclosure, and it is the reason a single agent can carry forty Skills without melting its context window. You can think of Skills as a filesystem-shaped library that the agent pulls from on demand.</p>\n<h3 id=\"a-few-things-skills-are-good-at\"><a class=\"heading-link\" href=\"#a-few-things-skills-are-good-at\">A few things Skills are good at</a></h3>\n<ul>\n<li><strong>Conventions.</strong> “Always wrap currency in this helper.” “Never call this deprecated function.” “Always cite a line number when you flag a bug.”</li>\n<li><strong>Multi-step workflows.</strong> “When the user asks to ship, run these checks in this order, then post in this Slack channel.”</li>\n<li><strong>Output formats.</strong> Slide templates, email shapes, weekly digest format, code review comments.</li>\n<li><strong>Domain knowledge.</strong> “Here is how our pricing model actually works. Here are the edge cases sales hits every month.”</li>\n</ul>\n<p>Anything that you would write down for a new teammate is a candidate for a Skill.</p>\n<h2 id=\"what-is-mcp-really\"><a class=\"heading-link\" href=\"#what-is-mcp-really\">What is MCP, really?</a></h2>\n<p>MCP, the Model Context Protocol, is a wire format. It is an open standard for an agent to talk to an outside system in a structured way. The agent is the client. A small server sits in front of GitHub, or Postgres, or Stripe, or your internal API, and exposes a list of <em>tools</em> the agent can call.</p>\n<p>A tool, in MCP terms, is a function the server says it can run, with a JSON schema for inputs. The agent reads the catalog at the start of the session, decides “I should call <code>search_issues</code> with this filter,” and the server runs the call. The result comes back as a message the agent can keep reasoning about.</p>\n<p>The win is reach. The model is no longer guessing what is in your Drive. It can search the Drive. It is not pretending to know your current quarterly numbers. It can run the query.</p>\n<h3 id=\"a-few-things-mcp-is-good-at\"><a class=\"heading-link\" href=\"#a-few-things-mcp-is-good-at\">A few things MCP is good at</a></h3>\n<ul>\n<li><strong>Live data.</strong> Anything that changes faster than you want to bake into a prompt. Inventory, tickets, calendars, deal stages.</li>\n<li><strong>Side effects.</strong> Sending the email, creating the ticket, deploying the branch.</li>\n<li><strong>Auth boundaries.</strong> When the data is locked behind an OAuth flow or a service token, MCP is where you put that.</li>\n<li><strong>Reusable across agents.</strong> One MCP server can serve Claude, Cursor, a custom agent, a future model you have not picked yet. Skills travel with the agent; MCP servers travel with the data.</li>\n</ul>\n<h2 id=\"the-hidden-cost-nobody-warns-you-about\"><a class=\"heading-link\" href=\"#the-hidden-cost-nobody-warns-you-about\">The hidden cost nobody warns you about</a></h2>\n<p>Here is the thing nobody puts in the marketing posts. MCP is not free at runtime. Every tool the server exposes goes into the agent’s context as part of the tool catalog, every single turn.</p>\n<p>Plug in three popular MCP servers (GitHub, a browser, an IDE) and you can burn a hundred and forty thousand tokens before the agent has done anything useful. There are real benchmarks floating around showing the same task taking four to thirty times more tokens through MCP than through a small CLI script the agent shells out to.</p>\n<p>Skills sidestep this almost completely. The Skill index lives in a hundred-token shelf. The body only loads when the task calls for it. You can have a hundred Skills installed and your context stays trim.</p>\n<p>This is not a knock on MCP. It is a planning constraint. When you reach for MCP, you are paying tokens for <em>access</em>. Make sure the access is worth it.</p>\n<h2 id=\"when-to-pick-which-in-10-seconds\"><a class=\"heading-link\" href=\"#when-to-pick-which-in-10-seconds\">When to pick which, in 10 seconds</a></h2>\n<p><img src=\"https://jubayeramb.com/assets/images/blog/ai-skills-vs-mcp/decision-flow.png\" alt=\"Decision flow card. Top question is whether the agent needs fresh data or to act on a system. If yes, reach for MCP, with examples like Drive search, Slack posts, DB queries. Second question is whether the task is about doing a recurring task well. If yes, write a Skill, with examples like house style, code review checklist, deck templates.\" width=\"1600\" height=\"900\" loading=\"lazy\" decoding=\"async\"></p>\n<p>In practice, the question to ask yourself is short.</p>\n<p><strong>Does the work need fresh, external state or a side effect on a system you do not own?</strong>\nThat is MCP. The agent must reach across a wire to do it correctly.</p>\n<p><strong>Is the work mostly about doing a recurring task the way your team does it?</strong>\nThat is a Skill. The know-how is the thing you are missing.</p>\n<p><strong>Both?</strong> Yes, usually. Most real workflows are MCP for the verbs and Skills for the style.</p>\n<h2 id=\"a-small-worked-example\"><a class=\"heading-link\" href=\"#a-small-worked-example\">A small worked example</a></h2>\n<p>Say you want an agent that ships your weekly customer digest.</p>\n<ul>\n<li>It needs to pull this week’s signups from your warehouse. <strong>MCP.</strong> A small server exposes a <code>query_warehouse(sql)</code> tool with read-only auth.</li>\n<li>It needs to pull last week’s support tickets. <strong>MCP.</strong> Your helpdesk vendor probably already publishes an MCP server.</li>\n<li>It needs to write the digest in your house voice, lead with a number, end with one sentence about what is next. <strong>Skill.</strong> Drop a <code>weekly-digest/</code> folder with <code>SKILL.md</code>, a tone guide, and three good past digests.</li>\n<li>It needs to post the digest in the <code>#growth</code> channel and tag the owner. <strong>MCP.</strong> A Slack MCP server gives you <code>post_message(channel, body)</code>.</li>\n</ul>\n<p>Notice how the seam falls. MCP shows up wherever the agent crosses a system boundary. Skills show up wherever the agent has to make a judgment call about <em>how good</em> the output should be.</p>\n<h2 id=\"the-short-rule-i-use\"><a class=\"heading-link\" href=\"#the-short-rule-i-use\">The short rule I use</a></h2>\n<p>When I am about to wire something up, I ask one question. <em>Is what I am giving the agent a recipe, or a key?</em></p>\n<p>A recipe is a Skill. A key is MCP.</p>\n<p>If it is both, the recipe goes in a Skill and the key goes behind an MCP server, and the agent picks them up at the moment it needs each one. That is the whole pattern. Once you see it, every new extension becomes obvious.</p>\n<p>If you found this useful, or you disagree with how I drew the line, I would love to hear about it. The fastest way to reach me is through the one of the channels on the <a href=\"https://jubayeramb.com/contact\">contact page</a>, or you can chat about me on the <a href=\"https://jubayeramb.com/\">home page</a> (yes, it is voice-enabled now).</p>",
      "date_published": "2026-05-12T00:00:00.000Z",
      "tags": [
        "Technical",
        "AI",
        "Agents",
        "Claude",
        "MCP",
        "Skills"
      ]
    },
    {
      "id": "https://jubayeramb.com/writings/2024-year-in-review-and-next-goals/",
      "url": "https://jubayeramb.com/writings/2024-year-in-review-and-next-goals/",
      "title": "2024 Year in Review and Setting Goals for 2025",
      "summary": "A look back at the successes, lessons, and hurdles of 2024, along with a roadmap for personal and professional growth in 2025.",
      "content_html": "<p>The year 2024 was a great year, but it didn’t go as planned for me. I had some goals set for the year, but I wasn’t able to accomplish most of them. While I managed to achieve a few of my goals, it obviously wasn’t enough. To be honest, I’m not happy with my progress this year. However, I finally took the time to sit down, reflect on the year, and set goals for the next one. I hope 2025 will be in my favor, and I’ll see some positive progress in my life.</p>\n<h2 id=\"2024-highlights\"><a class=\"heading-link\" href=\"#2024-highlights\">2024 Highlights</a></h2>\n<p>Reflecting on the key moments of 2024:</p>\n<ul>\n<li>Designed and developed a product MVP single-handedly and launched it for my company.</li>\n<li>Explored domestic destinations like <a href=\"https://en.wikipedia.org/wiki/St._Martin%27s_Island\">St. Martin’s Island</a> and <a href=\"https://en.wikipedia.org/wiki/Tanguar_Haor\">Tanguar Haor</a> with friends.</li>\n<li>Maintained consistent grades at university.</li>\n<li>Expanded my circle by making new friends on campus.</li>\n</ul>\n<h2 id=\"2024-evaluation\"><a class=\"heading-link\" href=\"#2024-evaluation\">2024 Evaluation</a></h2>\n<p>An assessment of the goals set for 2024:</p>\n<ol>\n<li>Build better personal habits.</li>\n<li>Write at least one line of code every day.</li>\n<li>Spend at least 15 hours weekly on coding side projects.</li>\n<li>Contribute to OSS.</li>\n<li>Write at least 5-10 blog posts.</li>\n<li>Regularly engage in physical exercise, preferably at a gym.</li>\n<li>Learn to recite the Quran with proper tajweed.</li>\n</ol>\n<p>I couldn’t accomplish most of the goals I set for 2024. Although I tried, I wasn’t able to fix my sleep schedule properly. I also tried to stay consistent with coding, but it wasn’t possible to code every day. The biggest <a href=\"https://en.wikipedia.org/wiki/2024_Bangladesh_quota_reform_movement\">Student Movement</a> in Bangladesh left us mentally exhausted; the internet was shut down for a long time, and I couldn’t work properly.</p>\n<p>I failed to start any side projects or contribute to OSS. I didn’t even write a single blog post this year; I almost forgot about this blog site! Other goals, like going to the gym, losing weight, and learning to recite the Quran with proper tajweed, were also left unaccomplished.</p>\n<p>These unachieved goals will be carried forward to my next year’s checklist. Let’s see if I can turn them into reality this time.</p>\n<h2 id=\"2025-goals\"><a class=\"heading-link\" href=\"#2025-goals\">2025 Goals</a></h2>\n<p>Setting ambitious targets for the upcoming year:</p>\n<p><strong><em>No new goals are added. The unaccomplished goals from 2024 will be carried forward to 2025.</em></strong></p>\n<h3 id=\"1-build-better-personal-habits\"><a class=\"heading-link\" href=\"#1-build-better-personal-habits\">1. Build better personal habits</a></h3>\n<p>Priorities include maintaining a consistent sleep schedule, adopting a healthier diet, and incorporating regular exercise. My primary goal is to establish a routine that starts each day after the Fajr prayer, emphasizing consistency.</p>\n<h3 id=\"2-spend-at-least-15-hours-weekly-on-coding-side-projects\"><a class=\"heading-link\" href=\"#2-spend-at-least-15-hours-weekly-on-coding-side-projects\">2. Spend at least 15 hours weekly on coding side projects</a></h3>\n<p>From building projects to solving real-world problems, I’ve learned that this is the best way to learn effectively. While I’ve worked on some side projects in the past, I need to be more consistent. I will dedicate at least 15 hours weekly to working on side projects to create something impactful.</p>\n<h3 id=\"3-contribute-to-oss\"><a class=\"heading-link\" href=\"#3-contribute-to-oss\">3. Contribute to OSS</a></h3>\n<p>I’ve contributed a negligible amount to OSS in the past, and I must do more. I’ve listed some projects of interest and will try to contribute to them. I’ll also explore and contribute to other interesting projects I come across.</p>\n<h3 id=\"4-write-at-least-5-10-blog-posts\"><a class=\"heading-link\" href=\"#4-write-at-least-5-10-blog-posts\">4. Write at least 5-10 blog posts</a></h3>\n<p>To build a regular writing habit, I planned and launched this blog site in November 2023. So far, I’ve written three blog posts. My goal is to write at least 5 to 10 blog posts in 2025. I already have some ideas; I just need to work on them incrementally.</p>\n<h3 id=\"5-regularly-engage-in-physical-exercise-preferably-at-a-gym\"><a class=\"heading-link\" href=\"#5-regularly-engage-in-physical-exercise-preferably-at-a-gym\">5. Regularly engage in physical exercise, preferably at a gym</a></h3>\n<p>I’ve gained significant weight in the past few years. I need to lose weight and get in shape. My plan is to visit the gym four days a week to shed some weight and gain muscle. A healthy diet will also be crucial.</p>\n<h3 id=\"6-learn-to-recite-the-quran-with-proper-tajweed\"><a class=\"heading-link\" href=\"#6-learn-to-recite-the-quran-with-proper-tajweed\">6. Learn to recite the Quran with proper tajweed</a></h3>\n<p>While I know how to recite the Quran, I haven’t mastered proper tajweed. I’ve learned some of the rules but need further guidance from a teacher.</p>\n<h3 id=\"7-plan-and-go-on-a-international-trip\"><a class=\"heading-link\" href=\"#7-plan-and-go-on-a-international-trip\">7. Plan and go on a international trip</a></h3>\n<p>I’ve visited several places within the country but have never traveled abroad. I have been planning to visit <a href=\"https://en.wikipedia.org/wiki/Nepal\">Nepal</a> or <a href=\"https://en.wikipedia.org/wiki/India\">India</a> for a long time. I hope to make it happen this year and perhaps visit other countries if possible.</p>\n<h3 id=\"8-become-a-better-developer\"><a class=\"heading-link\" href=\"#8-become-a-better-developer\">8. Become a better developer</a></h3>\n<p>This year, I explored cloud computing and advanced front-end concepts. I’ve learned and worked with tools like Astro and Svelte. My focus in 2025 will be to delve deeper into backend development and cloud technologies.</p>\n<h3 id=\"9-improve-communication-skills\"><a class=\"heading-link\" href=\"#9-improve-communication-skills\">9. Improve communication skills</a></h3>\n<p>I’ve made progress in improving my communication skills, such as speaking with people more confidently and making new friends. I’ve also improved my writing skills slightly. However, there’s still room for significant growth, particularly in maintaining a healthy routine and consistent diet and exercise.</p>\n<h2 id=\"conclusion\"><a class=\"heading-link\" href=\"#conclusion\">Conclusion</a></h2>\n<p>2024 was a year of mixed emotions. While I experienced some great moments, I also faced challenges. I couldn’t accomplish most of my goals, but I learned a lot from my failures.</p>\n<p>I’ve carried forward my unachieved goals to 2025, and I hope not to move them forward again! I aim to make 2025 a year of success and positivity.</p>\n<p>To follow my journey, stay tuned to this blog or connect with me on <a href=\"https://bsky.app/profile/jubayeramb.com\">Bluesky</a>, <a href=\"https://x.com/jubayeramb\">X</a>, or <a href=\"https://github.com/jubayeramb\">GitHub</a>.</p>\n<p>Wishing you all a very happy and prosperous New Year 2025! 🎉</p>",
      "date_published": "2024-12-31T00:00:00.000Z",
      "tags": [
        "Life",
        "Goals",
        "Career",
        "Year in review"
      ]
    },
    {
      "id": "https://jubayeramb.com/writings/2023-year-in-review-and-next-goals/",
      "url": "https://jubayeramb.com/writings/2023-year-in-review-and-next-goals/",
      "title": "2023 Year in Review and Next Goals",
      "summary": "Reflection on the accomplishments and challenges of the year 2023 and outline the goals for the next year.",
      "content_html": "<p>The year 2023 posed several challenges for me. I navigated through two job changes within the same year, finally securing a position that brings stability. Amidst juggling work, university, and other commitments, I haven’t been as productive as I would have liked to be. I have been able to accomplish some of my goals. But it seems to have done a bit better than the previous year.</p>\n<h2 id=\"2023-highlights\"><a class=\"heading-link\" href=\"#2023-highlights\">2023 Highlights</a></h2>\n<p>Reflecting on the key moments of 2023:</p>\n<ul>\n<li>Successfully securing a position in a company that aligns with my preferences, bringing satisfaction.</li>\n<li>Exploring domestic destinations like <a href=\"https://en.wikipedia.org/wiki/Sylhet\">Sylhet</a> and <a href=\"https://en.wikipedia.org/wiki/Sitakunda\">Sitakunda</a> with friends.</li>\n<li>Maintaining consistent grades at university.</li>\n<li>Expanding my circle by making new friends on campus.</li>\n<li>The decision to establish and develop this blog site.</li>\n</ul>\n<h2 id=\"2023-evaluation\"><a class=\"heading-link\" href=\"#2023-evaluation\">2023 Evaluation</a></h2>\n<p>An assessment of the goals set for 2023:</p>\n<ol>\n<li>Become a better developer.</li>\n<li>Improve my communication skills.</li>\n<li>Build better personal habits.</li>\n</ol>\n<p>I’d say I have been able to accomplish the first goal a bit. I have been able to learn a lot of new things and have been able to apply them in my work. I have also tried to improve my communication skills. I have been able to talk to people more and have been able to make some new friends. I have also been able to improve my writing skills a bit. But still, I have a long way to go. I have also been able to build some better personal habits but not all. But I still need to work on my diet, my sleep schedule and regular exercise.</p>\n<h2 id=\"2024-goals\"><a class=\"heading-link\" href=\"#2024-goals\">2024 Goals</a></h2>\n<p>Setting ambitious targets for the upcoming year:</p>\n<h3 id=\"1-build-better-personal-habits\"><a class=\"heading-link\" href=\"#1-build-better-personal-habits\">1. Build better personal habits</a></h3>\n<p>Priorities include maintaining a consistent sleep schedule, adopting a healthier diet, and incorporating regular exercise. The primary goal is to establish the routine of commencing each day after Fajr prayer, emphasizing consistency.</p>\n<h3 id=\"2-write-at-least-one-line-of-code-every-day\"><a class=\"heading-link\" href=\"#2-write-at-least-one-line-of-code-every-day\">2. Write at least one line of code every day</a></h3>\n<p>Committing to daily coding, regardless of project size, to foster consistency, productivity, and continuous learning.</p>\n<h3 id=\"3-spend-at-least-15-hours-weekly-on-coding-side-projects\"><a class=\"heading-link\" href=\"#3-spend-at-least-15-hours-weekly-on-coding-side-projects\">3. Spend at least 15 hours weekly on coding side projects</a></h3>\n<p>What I learnt is from building projects to solve real-wold problems and this is the best way to learn something effectively. I have been able to work on some side projects in the past but I need to be more consistent. I will dedicately spend at least 15 hours per week working on side projects to build some cool stuff.</p>\n<h3 id=\"4-contribute-to-oss\"><a class=\"heading-link\" href=\"#4-contribute-to-oss\">4. Contribute to OSS</a></h3>\n<p>I have contributed a negligible amount to OSS in the past. I must need to contribute more. So, I listed some projects of my interest and will try to contribute to them. I will also try to contribute to some other projects that I find interesting.</p>\n<h3 id=\"5-write-at-least-5-10-blog-posts\"><a class=\"heading-link\" href=\"#5-write-at-least-5-10-blog-posts\">5. Write at least 5-10 blog posts</a></h3>\n<p>In order to build a regular writing habit, I planned to build this blog site and got it done in November 2023. So far I have written 3 blog posts. So I have a goal to write at least 5-10 blog posts in the year 2024. I have some ideas for blog posts, I just need to write them down inchmeal.</p>\n<h3 id=\"6-regularly-engage-in-physical-exercise-preferably-at-a-gym\"><a class=\"heading-link\" href=\"#6-regularly-engage-in-physical-exercise-preferably-at-a-gym\">6. Regularly engage in physical exercise, preferably at a gym</a></h3>\n<p>I have gained a good amount of weight in the past few years. I need to lose some weight and get in shape. I have plan to go to a gym 4 days a week to lose some weight and gain some muscle. I also need to maintain a healthy diet.</p>\n<h3 id=\"7-learn-to-recite-the-quran-with-proper-tajweed\"><a class=\"heading-link\" href=\"#7-learn-to-recite-the-quran-with-proper-tajweed\">7. Learn to recite the Quran with proper tajweed</a></h3>\n<p>I have been able to recite the Quran but I don’t know how to recite it properly. I need to learn to recite the Quran with proper tajweed. I have been able to learn some of the rules of tajweed but I need to learn more from a teacher.</p>\n<h3 id=\"8-plan-and-go-on-a-international-trip\"><a class=\"heading-link\" href=\"#8-plan-and-go-on-a-international-trip\">8. Plan and go on a international trip</a></h3>\n<p>I have been to some places in the country but I have never been to any other country. I want to go on a international trip with my friends. I have been planning to go to <a href=\"https://en.wikipedia.org/wiki/India\">India</a> for a long time. I hope I will be able to go there this year and also visit some other countries if possible.</p>\n<h3 id=\"9-become-a-better-developer\"><a class=\"heading-link\" href=\"#9-become-a-better-developer\">9. Become a better developer</a></h3>\n<p>I have learnt some cloud stuffs in the past year and also gained some knowledge on advanced frontend concepts. I have learned and work with Astro and Svelte. I want to learn more backend stuff and cloud technologies this year.</p>\n<h3 id=\"10-improve-communication-skills\"><a class=\"heading-link\" href=\"#10-improve-communication-skills\">10. Improve communication skills</a></h3>\n<p>Continuing the journey to enhance communication, focusing on increased interaction, forging new connections, and refining writing skills through increased social media and blog engagement.</p>\n<h2 id=\"conclusion\"><a class=\"heading-link\" href=\"#conclusion\">Conclusion</a></h2>\n<p>These goals for 2024 are ambitious, and I’m eager to see them materialize. A year-end review post will evaluate the outcomes, aiming for accomplishment and growth. Follow my journey on <a href=\"https://twitter.com/jubayeramb\">Twitter</a> and <a href=\"https://github.com/jubayeramb\">GitHub</a>.</p>\n<p>Here’s to a promising year ahead! 🤞</p>\n<p>Thanks for reading! 🙏 Happy New Year! 🎉</p>",
      "date_published": "2023-12-31T00:00:00.000Z",
      "tags": [
        "Life",
        "Goals",
        "Career",
        "Year in review"
      ]
    },
    {
      "id": "https://jubayeramb.com/writings/handle-javascript-pormises-better/",
      "url": "https://jubayeramb.com/writings/handle-javascript-pormises-better/",
      "title": "Handle JavaScript Promises in a Better Way",
      "summary": "Learn different strategies to handle data and errors in JavaScript promises.",
      "content_html": "<p>If you’re familiar with what promises are, you can skip the next section and jump straight to the <a href=\"#initial-setup\">approaches</a>. Otherwise, read on!</p>\n<h2 id=\"what-are-promises\"><a class=\"heading-link\" href=\"#what-are-promises\">What are Promises?</a></h2>\n<p>The word “Promise” itself describes the concept of a commitment, signifying that something will occur in the future. A promise is a value that may not be available immediately but could be in the future.</p>\n<p>In JavaScript, a promise is an object that represents the eventual completion or failure of an asynchronous operation and its resulting value. The program’s execution does not halt while waiting for the promise to resolve; instead, it continues to execute the next line of code. The promise will be resolved or rejected at a later point. For example, a promise can be used to fetch data from an API. The promise will be resolved when the data is available, and the program can continue its execution. If an error occurs, the promise will be rejected, and the error can be handled appropriately.</p>\n<p>The promise object has three states: <em>Pending</em>, <em>Fulfilled</em>, and <em>Rejected</em>. Consequently, handling the fulfilled and rejected states of the promise is crucial to maintaining the smooth execution of our program.</p>\n<p>There are various ways to handle promises in JavaScript. In this article, we’ll explore some of the most common approaches to handling data and errors in promises, discussing the pros and cons of each approach. Let’s get started!</p>\n<h2 id=\"initial-setup\"><a class=\"heading-link\" href=\"#initial-setup\">Initial Setup</a></h2>\n<p>Suppose we have a function that returns a promise named <code>sayHi</code>. This function takes a boolean parameter called <code>shouldReject</code>. If <code>shouldReject</code> is <code>true</code>, the function returns a rejected promise; otherwise, it returns a resolved promise.</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">function</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">shouldReject</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">  return</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> new</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> Promise</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">resolve</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">reject</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (shouldReject) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">      reject</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"No, I won't say Hi! 😡\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">    resolve</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Hi! 😊\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  });</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<h2 id=\"approach-1-using-thencatch\"><a class=\"heading-link\" href=\"#approach-1-using-thencatch\">Approach 1: Using <code>then</code>/<code>catch</code></a></h2>\n<p>The first approach is to use the <code>then</code>/<code>catch</code> method. The <code>then</code> method handles the resolved data (usually), while <code>catch</code> deals with errors in promises. But both resolved data and errors can be handled in a single call using the <code>then</code> method.</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">().</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">then</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  (</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">result</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(result),</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  (</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">error</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(error)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span></code></pre>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>Hi! 😊</span></span></code></pre>\n<p>This approach is concise and convenient for simple scenarios. However, for complex chains with multiple promises, separate <code>then</code> and <code>catch</code> calls can enhance code readability and maintainability. This separation improves code organization, making success and error-handling logic clearer. For instance:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">then</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">result</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(result);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  })</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">catch</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">error</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(error);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  });</span></span></code></pre>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>No, I won't say Hi! 😡</span></span></code></pre>\n<p>While the <code>then</code>/<code>catch</code> method is common, it has some drawbacks. For instance, if multiple promises are used, the <code>catch</code> block captures errors from any point in the promise chain, leading to a lack of granularity in error handling.</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">then</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">result</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(result);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  })</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">then</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(() </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"This will not be executed\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    throw</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> new</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Error</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"This will not be caught by the next catch block\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  })</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">catch</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">error</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(error);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  });</span></span></code></pre>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>No, I won't say Hi! 😡</span></span></code></pre>\n<p>This problem can be mitigated by using the <code>catch</code> method on each promise, but this results in more verbose code. Nesting too many <code>then</code>/<code>catch</code> blocks can also lead to “promise hell,” making the code challenging to read and maintain.</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">then</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">result</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(result);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  })</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">catch</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">error</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(error);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  })</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">then</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(() </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"This will be executed\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    throw</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> new</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Error</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"This will be caught by the next catch block\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  })</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">catch</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">error</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(error.message);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  });</span></span></code></pre>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>No, I won't say Hi! 😡</span></span>\n<span class=\"line\"><span>This will be executed</span></span>\n<span class=\"line\"><span>This will be caught by the next catch block</span></span></code></pre>\n<p>While <code>then</code> and <code>catch</code> are still widely used, some developers prefer the cleaner and more concise syntax of <code>async</code>/<code>await</code> for handling promises, especially in scenarios where a more synchronous-looking code is desired.</p>\n<h2 id=\"approach-2-using-asyncawait\"><a class=\"heading-link\" href=\"#approach-2-using-asyncawait\">Approach 2: Using <code>async</code>/<code>await</code></a></h2>\n<p>The second approach involves using <code>async</code>/<code>await</code>. The <code>async</code> keyword defines an asynchronous function, while <code>await</code> is used to wait for a promise to resolve. The <code>await</code> keyword can only be used inside an <code>async</code> function and will pause the function’s execution until the promise is resolved. It also catches any errors thrown by the promise, which can be handled using a <code>try</code>/<code>catch</code> block.</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">async</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> function</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> asyncWrapper</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">() {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">  try</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    const</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> result</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> =</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> await</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">();</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(result);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">catch</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (error) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(error);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">asyncWrapper</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">();</span></span></code></pre>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>Hi! 😊</span></span></code></pre>\n<p>The <code>async</code>/<code>await</code> syntax can be combined with the <code>catch</code> method syntax:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">const</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> message</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> =</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> await</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">).</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">catch</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">error</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(error);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">});</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(message);</span></span></code></pre>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>No, I won't say Hi! 😡</span></span></code></pre>\n<p>However, a drawback is that if a rejection occurs, the execution of the next line where <code>message</code> is being used cannot be stopped. Additionally, outside the <code>catch</code> block, there is no access to the <code>error</code> object, making it impossible to check for errors before the execution of the next line.</p>\n<p>Despite these limitations, the <code>async</code>/<code>await</code> syntax is more concise and easier to read than the <code>then</code>/<code>catch</code> syntax. It allows for more granular error handling using the <code>try</code>/<code>catch</code> block and includes a <code>finally</code> block to execute code after the promise is resolved or rejected.</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">async</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> function</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> asyncWrapper</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">() {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">  try</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    const</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> result</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> =</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> await</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(result);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">catch</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (error) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(error);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">finally</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"This will be executed regardless of the promise's state\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">asyncWrapper</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">();</span></span></code></pre>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>No, I won't say Hi! 😡</span></span>\n<span class=\"line\"><span>This will be executed regardless of the promise's state</span></span></code></pre>\n<p>We can also go with kinda <code>callback</code> pattern we’re used to within Node.js. We can get both the data and the error from a single call and can easily handle them.</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">async</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> function</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> asyncWrapper</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">promise</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">  try</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    const</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> result</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> =</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> await</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> promise;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    return</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> [result];</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">catch</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (error) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    return</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> [, error];</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">const</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> [</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">message</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">error</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">] </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> await</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> asyncWrapper</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">());</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (error) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(error);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">} </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">else</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(message);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>Hi! 😊</span></span></code></pre>\n<blockquote>\n<p>Note: <code>null</code> or <code>undefined</code> can be returned instead of an empty array, for example, <code>return [result, null]</code> or <code>return [result, undefined]</code>. Another approach utilizing the <code>Promise.allSettled</code> method will be discussed shortly.</p>\n</blockquote>\n<h2 id=\"approach-3-using-promiseallsettled\"><a class=\"heading-link\" href=\"#approach-3-using-promiseallsettled\">Approach 3: Using <code>Promise.allSettled</code></a></h2>\n<p>Concurrent promises can be handled using the <code>Promise.all</code> and <code>Promise.allSettled</code> methods. <code>Promise.allSettled</code> is used to wait for all promises to be settled. It takes an array of promises as an argument and returns a promise that is resolved when all promises are settled. The promise returned includes an array of objects, each with a <code>status</code> property and\na <code>value</code> when fulfilled or a <code>reason</code> when rejected.</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">Promise</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">allSettled</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">([</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">), </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">false</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)]).</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">then</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">results</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(results);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">});</span></span></code></pre>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>[</span></span>\n<span class=\"line\"><span>   { status: 'rejected', reason: 'No, I won\\'t say Hi! 😡' },</span></span>\n<span class=\"line\"><span>   { status: 'fulfilled', value: 'Hi! 😊' }</span></span>\n<span class=\"line\"><span>]</span></span></code></pre>\n<p>If promises depend on each other, and immediate rejection is desired if any fails, <code>Promise.all</code> can be used. This method waits for all promises to be resolved and is rejected immediately if any promise is rejected. Errors can be handled using the <code>catch</code> method.</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">Promise</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">all</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">([</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">false</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">), </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">false</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">), </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">Promise</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">resolve</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Resolved!! 😁\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)])</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">then</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">results</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(results);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  })</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">catch</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">error</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(error);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  });</span></span></code></pre>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>[ 'Hi! 😊', 'Hi! 😊', 'Resolved!! 😁' ]</span></span></code></pre>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">Promise</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">all</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">([</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">true</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">), </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">false</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">), </span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">false</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)])</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">then</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">results</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(results);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  })</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">catch</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">((</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">error</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(error);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  });</span></span></code></pre>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>No, I won't say Hi! 😡</span></span></code></pre>\n<p>The <code>async</code>/<code>await</code> syntax for handling data and errors in a single call can be achieved using the <code>Promise.allSettled</code> method:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">function</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> asyncWrapper</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">promise</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">  return</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> Promise</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">allSettled</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">([promise]).</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">then</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(([{ </span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">value</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">reason</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> }]) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> [</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    value,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    reason,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  ]);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">const</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> [</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">message</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">error</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">] </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> await</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> asyncWrapper</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">sayHi</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">());</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (error) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(error);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">} </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">else</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  console.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">log</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(message);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"plaintext\"><code><span class=\"line\"><span>Hi! 😊</span></span></code></pre>\n<p>This approach appears more concise and readable than the <code>async</code>/<code>await</code> syntax!</p>\n<blockquote>\n<p>Other methods such as <code>Promise.race</code> and <code>Promise.any</code> exist to handle concurrent promises. You can read more about these <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#promise_concurrency\">here</a>.</p>\n</blockquote>\n<h2 id=\"conclusion\"><a class=\"heading-link\" href=\"#conclusion\">Conclusion</a></h2>\n<p>In this article, we explored different ways to handle errors in JavaScript promises, discussing the pros and cons of each approach. I hope you found this article useful. Thanks for reading! 😊</p>",
      "date_published": "2023-12-09T00:00:00.000Z",
      "tags": [
        "Technical",
        "JavaScript",
        "Promises",
        "Error handling"
      ]
    },
    {
      "id": "https://jubayeramb.com/writings/add-dark-mode-tailwind-css-astro/",
      "url": "https://jubayeramb.com/writings/add-dark-mode-tailwind-css-astro/",
      "title": "Tailwind CSS Dark Mode without `dark:` Prefixes",
      "summary": "Add dark mode to your Astro (or whatever) website using Tailwind CSS without `dark:` prefixes. Also supports `prefers-color-scheme` media query.",
      "content_html": "<p>A quick guide on how to add dark mode to your Astro (or whatever) website using Tailwind CSS without <code>dark:</code> prefixes. Also supports <code>prefers-color-scheme</code> media query. <br>\nIn this blog, I will show you how to add dark mode to a Astro website. This will also work with any other framework or even vanilla HTML/CSS/JS. <br>\nYou can check the complete source code of this blog on <a href=\"https://github.com/jubayeramb/astro-tailwind-dark-theme\">GitHub</a>.</p>\n<h2 id=\"1-initial-setup\"><a class=\"heading-link\" href=\"#1-initial-setup\">1. Initial setup</a></h2>\n<p>Initialize an Astro project by running the following command in your terminal:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">npm</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> create</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> astro@latest</span></span></code></pre>\n<blockquote>\n<p>You can use your preferred package manager (<code>yarn</code> or <code>pnpm</code>) instead of <code>npm</code> if you want.</p>\n</blockquote>\n<p>You can choose to use the default template or any other template you want. I will be using the default template for this blog. You can go with or without TypeScript.\nOnce your project is initialized and dependencies are installed, you can start the dev server by running:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">npm</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> run</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> dev</span></span></code></pre>\n<p>The default dev server will be running on <code>localhost:4321</code>.</p>\n<h2 id=\"2-add-tailwind-css\"><a class=\"heading-link\" href=\"#2-add-tailwind-css\">2. Add Tailwind CSS</a></h2>\n<p>You can add Tailwind CSS to your project by running the following command in your terminal:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"bash\"><code><span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">npx</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> astro</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> add</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> tailwind</span></span></code></pre>\n<p>The <code>astro add</code> CLI command will automatically install the required dependencies and add the required Tailwind configuration to your project. So you’re now good to go with Tailwind CSS!</p>\n<blockquote>\n<p>You can also add Tailwind CSS manually by following the <a href=\"https://docs.astro.build/en/guides/integrations-guide/tailwind/#manual-install\">Manual Tailwind CSS installation documentation</a> on Astro doc.</p>\n</blockquote>\n<h2 id=\"3-clean-up-the-project-optional\"><a class=\"heading-link\" href=\"#3-clean-up-the-project-optional\">3. Clean up the project (optional)</a></h2>\n<p>If you chose the empty template, you don’t need to follow this step. But if you chose any other template, you can clean up the project by removing the unnecessary files and code. You can remove the following files and folders:</p>\n<ul>\n<li><code>src/pages/index.astro</code></li>\n<li><code>src/components/Card.astro</code></li>\n</ul>\n<p>Now create a new file <code>src/pages/index.astro</code> and add the following code:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"astro\"><code><span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">---</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> Layout </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">from</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"../layouts/Layout.astro\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">---</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">Layout</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> title</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Your Site\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">main</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> class</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"w-full h-screen flex items-center justify-center\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">h1</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> class</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"font-bold text-2xl\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>Welcome To Your Site&#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">h1</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  &#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">main</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;/</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">Layout</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span></code></pre>\n<p>Also replace the content of <code>src/layouts/Layout.astro</code> with the following code:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"astro\"><code><span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">---</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">interface</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Props</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">    title</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">:</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> string</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">const</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">title</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> Astro.props;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">---</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;!</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">doctype</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> html</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">html</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> lang</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"en\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">head</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">meta</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> charset</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"UTF-8\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> /></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">meta</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> name</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"description\"</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> content</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Your site description\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> /></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">meta</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> name</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"viewport\"</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> content</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"width=device-width\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> /></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">link</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> rel</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"icon\"</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> type</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"image/svg+xml\"</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> href</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"/favicon.svg\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> /></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">meta</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> name</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"generator\"</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> content</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">={Astro.generator} /></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">title</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">>{title}&#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">title</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  &#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">head</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">body</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">slot</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> /></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  &#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">body</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">html</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span></code></pre>\n<blockquote>\n<p><strong>Notice</strong> defining the <code>Props</code> type helps you getting type support for the component incoming props. If you didn’t choose TypeScript, you can remove the <code>Props</code> interface.</p>\n</blockquote>\n<p>Now you can save the files and check the browser (make suer the dev server is running). You should see a page with a title “Welcome To Your Site” placed in the center of the page. <em><strong>Notice that the Tailwind CSS is already working.</strong></em></p>\n<h2 id=\"4-add-dark-mode\"><a class=\"heading-link\" href=\"#4-add-dark-mode\">4. Add dark mode</a></h2>\n<p>Now we will add dark mode to our website. We will be using the <code>prefers-color-scheme</code> media query to detect the user’s system preference by default and then we will add a toggle button to switch between light and dark mode.\nTo skip the <code>dark:</code> prefixes, we will take advantage of the Tailwind color palette customization and CSS variables. First we will declare two color variable in our <code>./src/styles/global.css</code> file and define the colors in the <code>tailwind.config.js</code> file and then we will use the <code>bg-[color]</code> and <code>text-[color]</code> classes to apply the colors to the elements.</p>\n<h3 id=\"41-add-color-variables\"><a class=\"heading-link\" href=\"#41-add-color-variables\">4.1. Add color variables</a></h3>\n<p>Create a <code>global.css</code> file in the <code>./src/styles/</code> directory and add the following code:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"css\"><code><span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">@tailwind</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> base;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">@tailwind</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> components;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">@tailwind</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> utilities;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">@layer</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> base {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  :root</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  :root</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">[</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">data-theme</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"light\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">] {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">    --color-bgColor</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">221</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 230</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 237</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">    --color-contentColor</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">34</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 40</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 49</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">    --sun-fill</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">rgb</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">0</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">    --moon-fill</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">transparent</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">  @media</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (prefers-color-scheme: dark) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">    :root</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">      --color-bgColor</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">34</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 40</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 49</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">      --color-contentColor</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">238</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 238</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 238</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">      --sun-fill</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">transparent</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">      --moon-fill</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">rgb</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">255</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">255</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">255</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  :root</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">[</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">data-theme</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"dark\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">] {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">    --color-bgColor</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">34</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 40</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 49</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">    --color-contentColor</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">238</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 238</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> 238</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">    --sun-fill</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">transparent</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">    --moon-fill</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">: </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">rgb</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">255</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">255</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">255</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span></code></pre>\n<blockquote>\n<p>Here we are using the <code>--color-bgColor</code> and <code>--color-contentColor</code> variables to define the background and content colors. We are also using the <code>--sun-fill</code> and <code>--moon-fill</code> variables to define the fill color of the sun and moon icons. We will use these variables in the <code>tailwind.config.js</code> file to define the colors.</p>\n</blockquote>\n<blockquote>\n<p><strong>Notice</strong> that we are using the <code>:root[data-theme=\"light\"]</code> and <code>:root[data-theme=\"dark\"]</code> selectors to define the colors. We will use the <code>data-theme</code> attribute to switch between light and dark mode. We’re also using the <code>prefers-color-scheme</code> media query to detect the user’s system preference by default.</p>\n</blockquote>\n<h3 id=\"42-add-color-definitions\"><a class=\"heading-link\" href=\"#42-add-color-definitions\">4.2. Add color definitions</a></h3>\n<p>Now open the <code>tailwind.config.cjs</code> file and add the following code:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"js\"><code><span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">/** </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">@type</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> {import('tailwindcss').Config}</span><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\"> */</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">export</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> default</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  content: [</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">],</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  theme: {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    extend: {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      colors: {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        bgColor: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"rgb(var(--color-bgColor) / &#x3C;alpha-value>)\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">        contentColor: </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"rgb(var(--color-contentColor) / &#x3C;alpha-value>)\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">,</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      },</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    },</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  },</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  plugins: [],</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">};</span></span></code></pre>\n<h3 id=\"43-import-global-styles\"><a class=\"heading-link\" href=\"#43-import-global-styles\">4.3. Import global styles</a></h3>\n<p>Usually you will be using the <code>Layout.astro</code> component to wrap your other pages. So import the <code>global.css</code> file in the <code>./src/layouts/Layout.astro</code> file frontmatter (otherwise add it to the <code>index.astro</code> file, if you’re not using the <code>Layout.astro</code> component) like this:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"astro\"><code><span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">---</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">interface</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> Props</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#B04800;--shiki-dark:#FFAB70\">    title</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">:</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> string</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">const</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> { </span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">title</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> Astro.props;</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">import</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"../styles/global.css\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">---</span></span></code></pre>\n<p>Now all you need to do is to use the <code>bg-bgColor</code> and <code>text-contentColor</code> classes to apply the colors to the elements. For example, you can replace the <code>&#x3C;body></code> element of the <code>./src/layouts/Layout.astro</code> wrapper file with the following code:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"astro\"><code><span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">body</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> class</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"text-contentColor bg-bgColor\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">slot</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> /></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  &#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">body</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span></code></pre>\n<p><strong>Wohoo! You have successfully added dark mode to your website!</strong> 🔥 <br>\nNow your site will respond to the user’s system preference. Toggle your System theme to see the effect on your site. But we still need to add a toggle button for the user to switch between light and dark mode manually.</p>\n<h3 id=\"44-add-a-toggle-button\"><a class=\"heading-link\" href=\"#44-add-a-toggle-button\">4.4. Add a toggle button</a></h3>\n<p>Now we will add a toggle button to switch between light and dark mode manually. We will use the <code>data-theme</code> attribute to switch between light and dark mode. We will also use the <code>--sun-fill</code> and <code>--moon-fill</code> variables to define the fill color of the sun and moon icons. We will use the <code>bg-bgColor</code> and <code>text-contentColor</code> classes to apply the colors to the elements.</p>\n<p>Create a <code>ThemeIcon.astro</code> file into the <code>./src/components/</code> directory and add the following code:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"astro\"><code><span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">---</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">---</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">button</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  id</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"themeToggle\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  class</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"border-0 bg-none hover:bg-slate-300/20 p-2 rounded-full\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">  aria-label</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"Toggle dark mode\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">svg</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> width</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"20px\"</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> xmlns</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"http://www.w3.org/2000/svg\"</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> viewBox</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"0 0 24 24\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">    &#x3C;!-- sun --></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">path</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">      class</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"fill-[--sun-fill]\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">      fill-rule</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"evenodd\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">      d</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"M12 17.5a5.5 5.5 0 1 0 0-11 5.5 5.5 0 0 0 0 11zm0 1.5a7 7 0 1 0 0-14 7 7 0 0 0 0 14zm12-7a.8.8 0 0 1-.8.8h-2.4a.8.8 0 0 1 0-1.6h2.4a.8.8 0 0 1 .8.8zM4 12a.8.8 0 0 1-.8.8H.8a.8.8 0 0 1 0-1.6h2.5a.8.8 0 0 1 .8.8zm16.5-8.5a.8.8 0 0 1 0 1l-1.8 1.8a.8.8 0 0 1-1-1l1.7-1.8a.8.8 0 0 1 1 0zM6.3 17.7a.8.8 0 0 1 0 1l-1.7 1.8a.8.8 0 1 1-1-1l1.7-1.8a.8.8 0 0 1 1 0zM12 0a.8.8 0 0 1 .8.8v2.5a.8.8 0 0 1-1.6 0V.8A.8.8 0 0 1 12 0zm0 20a.8.8 0 0 1 .8.8v2.4a.8.8 0 0 1-1.6 0v-2.4a.8.8 0 0 1 .8-.8zM3.5 3.5a.8.8 0 0 1 1 0l1.8 1.8a.8.8 0 1 1-1 1L3.5 4.6a.8.8 0 0 1 0-1zm14.2 14.2a.8.8 0 0 1 1 0l1.8 1.7a.8.8 0 0 1-1 1l-1.8-1.7a.8.8 0 0 1 0-1z\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    >&#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">path</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">    &#x3C;!-- moon --></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">path</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">      class</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"fill-[--moon-fill]\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">      fill-rule</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"evenodd\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">      d</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"M16.5 6A10.5 10.5 0 0 1 4.7 16.4 8.5 8.5 0 1 0 16.4 4.7l.1 1.3zm-1.7-2a9 9 0 0 1 .2 2 9 9 0 0 1-11 8.8 9.4 9.4 0 0 1-.8-.3c-.4 0-.8.3-.7.7a10 10 0 0 0 .3.8 10 10 0 0 0 9.2 6 10 10 0 0 0 4-19.2 9.7 9.7 0 0 0-.9-.3c-.3-.1-.7.3-.6.7a9 9 0 0 1 .3.8z\"</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    >&#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">path</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  &#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">svg</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">button</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">script</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> is:inline</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">const</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> attributeName</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> =</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"data-theme\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">const</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> theme</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> =</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (() </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">  if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">typeof</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> localStorage </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">!==</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"undefined\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    return</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> localStorage.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">getItem</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"theme\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">||</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> null</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">})();</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">!!</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">theme) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  document.documentElement.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setAttribute</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(attributeName, theme);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">const</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> handleToggleClick</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> =</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> () </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">=></span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">  const</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> element</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> =</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> document.documentElement;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">  const</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\"> themeAtt</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> =</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> element.attributes.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">getNamedItem</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(attributeName)?.value;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">  // no att. and system is dark</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">  if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    !</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">themeAtt </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">&#x26;&#x26;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    window.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">matchMedia</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"(prefers-color-scheme: dark)\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">).matches</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  ) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    element.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setAttribute</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(attributeName, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"light\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    window.localStorage.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setItem</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"theme\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"light\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    return</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">else</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">!</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">themeAtt) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">    // no att. and system is light</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    element.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setAttribute</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(attributeName, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"dark\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    window.localStorage.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setItem</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"theme\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"dark\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    return</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">else</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (themeAtt </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">===</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"light\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">    // light att.</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    element.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setAttribute</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(attributeName, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"dark\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    window.localStorage.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setItem</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"theme\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"dark\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    return</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  } </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">else</span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\"> if</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> (themeAtt </span><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">===</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\"> \"dark\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">) {</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#5A636E;--shiki-dark:#6A737D\">    // dark att.</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    element.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setAttribute</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(attributeName, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"light\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    window.localStorage.</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">setItem</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"theme\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, </span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"light\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#C4303F;--shiki-dark:#F97583\">    return</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">;</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  }</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">};</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">document</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">getElementById</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"themeToggle\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">)</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  .</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\">addEventListener</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">(</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"click\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">, handleToggleClick);</span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">&#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">script</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span></code></pre>\n<blockquote>\n<p>Here we are using a SVG icon to toggle between light and dark mode (you can update the icon as of your choice). We are also using the <code>localStorage</code> API to store the user’s preference. We are using the <code>data-theme</code> attribute to switch between light and dark mode. We are also using the <code>--sun-fill</code> and <code>--moon-fill</code> variables to define the fill color of the sun and moon icons. We are using the <code>bg-bgColor</code> and <code>text-contentColor</code> classes to apply the colors to the elements.</p>\n</blockquote>\n<p>Now you can import the <code>ThemeIcon.astro</code> component in the <code>./src/layouts/Layout.astro</code> file and place it anywhere you want. For example, you can place it in the <code>&#x3C;body></code> element of the <code>./src/layouts/Layout.astro</code> wrapper file like this:</p>\n<pre class=\"astro-code astro-code-themes github-light github-dark\" style=\"--shiki-light:#24292e;--shiki-dark:#e1e4e8;--shiki-light-bg:#fff;--shiki-dark-bg:#24292e; overflow-x: auto;\" tabindex=\"0\" data-language=\"astro\"><code><span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">body</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> class</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"text-contentColor bg-bgColor\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">div</span><span style=\"--shiki-light:#6F42C1;--shiki-dark:#B392F0\"> class</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">=</span><span style=\"--shiki-light:#032F62;--shiki-dark:#9ECBFF\">\"flex justify-center\"</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">      &#x3C;</span><span style=\"--shiki-light:#005CC5;--shiki-dark:#79B8FF\">ThemeIcon</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> /></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">div</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">    &#x3C;</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">slot</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\"> /></span></span>\n<span class=\"line\"><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">  &#x3C;/</span><span style=\"--shiki-light:#1B7C34;--shiki-dark:#85E89D\">body</span><span style=\"--shiki-light:#24292E;--shiki-dark:#E1E4E8\">></span></span></code></pre>\n<blockquote>\n<p>You can create a Nav component and place the <code>ThemeIcon.astro</code> component in the Nav component.</p>\n</blockquote>\n<p><strong>Congratulations! You did it! You Added a dynamic dark theme to your site!</strong> 🎉 <br>\nYou don’t even need to add the <code>dark:</code> prefixes to the every Tailwind CSS classes where you need to add dark theme variant. You can use the <code>bgColor</code> and <code>contentColor</code> color variant to apply the colors to the elements and the site will automatically adjust the theme color. <br>\nNow you can save the files and check the browser (make suer the dev server is running). You should see a toggle button in the center of the page. Click on the button to switch between light and dark mode.</p>\n<p>Thanks for reading! 🙏 <br></p>",
      "date_published": "2023-11-10T00:00:00.000Z",
      "tags": [
        "Technical",
        "Astro",
        "Tailwind CSS",
        "CSS",
        "HTML",
        "JavaScript"
      ]
    }
  ]
}