<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Bao Huynh Lam</title>
    <description>The latest articles on Forem by Bao Huynh Lam (@bhuynhdev).</description>
    <link>https://forem.com/bhuynhdev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F523200%2F81682792-3318-4e3a-846a-fed84d830e70.jpeg</url>
      <title>Forem: Bao Huynh Lam</title>
      <link>https://forem.com/bhuynhdev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/bhuynhdev"/>
    <language>en</language>
    <item>
      <title>3 cool things about the `create-vite` CLI you might not have known</title>
      <dc:creator>Bao Huynh Lam</dc:creator>
      <pubDate>Sun, 08 Feb 2026 05:35:47 +0000</pubDate>
      <link>https://forem.com/bhuynhdev/3-cool-things-about-the-create-vite-cli-you-might-not-have-known-13ij</link>
      <guid>https://forem.com/bhuynhdev/3-cool-things-about-the-create-vite-cli-you-might-not-have-known-13ij</guid>
      <description>&lt;p&gt;I wanted to learn how to make pleasant and interactive CLI like the &lt;code&gt;creat-vite&lt;/code&gt; project scaffolding CLI, so yesterday I took a quick dive into the code of &lt;code&gt;create-vite&lt;/code&gt; (note: not &lt;code&gt;vite&lt;/code&gt; itself) to study what magical sauces they have and hopefully learn some cool new techniques along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  At a glance
&lt;/h2&gt;

&lt;p&gt;Everything starts in the &lt;code&gt;init&lt;/code&gt; function of the &lt;code&gt;src/index.ts&lt;/code&gt; &lt;a href="https://github.com/vitejs/vite/blob/945318269df861afe4f3f80bfb12b784a93fd547/packages/create-vite/src/index.ts#L446" rel="noopener noreferrer"&gt;file&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At a glance, we can see that the CLI progresses through 6 stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Get (or ask for) project name and target directory&lt;/li&gt;
&lt;li&gt;Handle directory if exist and not empty&lt;/li&gt;
&lt;li&gt;Get package name (if the project name at step 1 is an invalid NPM package name)&lt;/li&gt;
&lt;li&gt;ASk users to choose a framework and variant&lt;/li&gt;
&lt;li&gt;Ask user if immediate install is desired&lt;/li&gt;
&lt;li&gt;Finally starts scaffolding folders and files&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The main "ingredients" for this elegant experience includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;mri&lt;/code&gt; library for working with CLI arguments&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@clack/prompts&lt;/code&gt; library for displaying pretty interactive prompts&lt;/li&gt;
&lt;li&gt;And &lt;code&gt;picocolors&lt;/code&gt; for adding colors to the console log&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, the &lt;code&gt;create-vite&lt;/code&gt; CLI is a pretty straightforward and simple tool. Diving into the code, I learned some interesting details.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cool thing 1 - All the different CLI flags
&lt;/h2&gt;

&lt;p&gt;On README, you might see that &lt;code&gt;create-vite&lt;/code&gt; CLI supports the &lt;code&gt;--template&lt;/code&gt; flag, but that's not the only one. Here are some more:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--overwrite&lt;/code&gt; / &lt;code&gt;--no-overwrite&lt;/code&gt;: Should Vite overwrite if a non-empty directory already exists at your target location?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--immediate&lt;/code&gt; / &lt;code&gt;--no-immediate&lt;/code&gt;: Marks your preference for step (5) - i.e. do you want immediate install and starting the Dev server after scaffolding?&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--interactive&lt;/code&gt; (&lt;code&gt;-i&lt;/code&gt;) / &lt;code&gt;--no-interactive&lt;/code&gt;: Should Vite prompt you for answer, or assume default values? By default, the template is &lt;code&gt;vanilla-ts&lt;/code&gt; if none is provided, and &lt;code&gt;overwrite&lt;/code&gt; and &lt;code&gt;immediate&lt;/code&gt; is false. The No-Interactive mode is useful when running &lt;code&gt;create-vite&lt;/code&gt; as part of some unmonitored CI/CD pipeline, or if an AI agent is running commands.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Additionally, here are the full list of template names that you can pass into the &lt;code&gt;--template&lt;/code&gt; argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// vanilla
"vanilla-ts",
"vanilla",

// vue
"vue-ts",
"vue",
"custom-create-vue",
"custom-nuxt",
"custom-vike-vue",

// react
"react-ts",
"react-compiler-ts",
"react-swc-ts",
"react",
"react-compiler",
"react-swc",
"rsc",
"custom-react-router",
"custom-tanstack-router-react",
"redwoodsdk-standard",
"custom-vike-react",

// preact
"preact-ts",
"preact",
"custom-create-preact",

// lit
"lit-ts",
"lit",

// svelte
"svelte-ts",
"svelte",
"custom-svelte-kit",

// solid
"solid-ts",
"solid",
"custom-tanstack-router-solid",
"custom-vike-solid",

// ember
"ember-app-ts",
"ember-app",

// qwik
"qwik-ts",
"qwik",
"custom-qwik-city",

// angular
"custom-angular",
"custom-analog",

// marko
"marko-run",

// others
"create-vite-extra",
"create-electron-vite"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cool thing 2 - "Support" for AI agent
&lt;/h2&gt;

&lt;p&gt;This is a fun little detail, but &lt;code&gt;create-vite&lt;/code&gt; uses &lt;a href="https://www.npmjs.com/package/@vercel/detect-agent" rel="noopener noreferrer"&gt;&lt;code&gt;@vercel/detect-agent&lt;/code&gt;&lt;/a&gt; to determine if an agent is running the CLI. And if &lt;code&gt;isAgent&lt;/code&gt; and interactive mode is enabled, the CLI will log a helpful message for the agent:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To create in one go, run: create-vite  --no-interactive --template &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Cool thing 3 - Some coding techniques
&lt;/h2&gt;

&lt;p&gt;Here are some cool programming techniques I though were very interesting:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Determining the package manager via &lt;code&gt;npm_config_user_agent&lt;/code&gt; ENV&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ever wondered how a CLI can determine what package manager you used, so it can continue using that in subsequent commands? It's all thanks to the &lt;code&gt;npm_config_user_agent&lt;/code&gt; environment variable. Each package manager sets the variable accordingly (like how &lt;code&gt;pnpm&lt;/code&gt; does &lt;a href="https://github.com/pnpm/pnpm/issues/3985" rel="noopener noreferrer"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Example: You can run &lt;code&gt;pnpm config get user-agent&lt;/code&gt; to get the full agent string:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm/10.20.0 npm/? node/v20.11.1 linux x64
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;Then you can split by space and then by slash to &lt;a href="https://github.com/vitejs/vite/blob/945318269df861afe4f3f80bfb12b784a93fd547/packages/create-vite/src/index.ts#L777" rel="noopener noreferrer"&gt;get the package manager name&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Detect whether standard input is connected to a terminal or not via &lt;code&gt;process.stdin.isTTY&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The terminal input can also be piped in (like &lt;code&gt;cat data.txt | xargs pnpm create-vite&lt;/code&gt;), in which case interactivity won't be possible. As a result, the CLI only enables interactive mode if &lt;code&gt;isTTY&lt;/code&gt; is true.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Handling Control-C gracefully&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After every prompt, I noticed that there is always a check to see if the user has cancelled the command so that we can gracefully display the message "Operation Cancelled".&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prompts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isCancel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;projectName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This technique feels so obvious in retrospect (and the &lt;code&gt;@clack/prompts&lt;/code&gt; creator also &lt;a href="https://npmx.dev/package/@clack/prompts" rel="noopener noreferrer"&gt;recommends so&lt;/a&gt;), but seeing how it is employed in production-ready code base somehow really cements it for me.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  In summary - lessons I learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;mri&lt;/code&gt;, &lt;code&gt;@clack/prompts&lt;/code&gt;, and &lt;code&gt;picocolors&lt;/code&gt; are a quick combo to create a very pleasant CLI&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;process.env.npm_config_user_agent&lt;/code&gt; to detect what package manager was used&lt;/li&gt;
&lt;li&gt;If you're using &lt;code&gt;@clack/prompts&lt;/code&gt;: Check &lt;code&gt;prompts.isCancel&lt;/code&gt; to handle control-C gracefully&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>vite</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Typescript and HTML attributes in various frameworks</title>
      <dc:creator>Bao Huynh Lam</dc:creator>
      <pubDate>Thu, 02 Jan 2025 00:28:46 +0000</pubDate>
      <link>https://forem.com/bhuynhdev/typescript-and-html-attributes-in-various-frameworks-38j8</link>
      <guid>https://forem.com/bhuynhdev/typescript-and-html-attributes-in-various-frameworks-38j8</guid>
      <description>&lt;p&gt;If you have worked with Typescript in a JavaScript framework - React, Vue, Solid, or Svelte - then you might have needed/will need to create wrapper/mirror components that encompasses native HTML elements.&lt;/p&gt;

&lt;p&gt;For example: An enhanced &lt;code&gt;&amp;lt;Link&amp;gt;&lt;/code&gt; wrapper over the &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; element. Or a custom &lt;code&gt;&amp;lt;Button&amp;gt;&lt;/code&gt; component that behaves like a &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; - and be able accept all relevant attributes like &lt;code&gt;type&lt;/code&gt;, &lt;code&gt;style&lt;/code&gt;, &lt;code&gt;aria-&lt;/code&gt;, etc. - but also allow passing in your own custom &lt;code&gt;variant&lt;/code&gt; prop.&lt;/p&gt;

&lt;p&gt;In such case, you would want to Typescript your component's props to &lt;strong&gt;extend&lt;/strong&gt; the list of attributes that the underlying HTML component accepts.&lt;/p&gt;

&lt;p&gt;Fortunately, all frameworks offer type helpers to achieve this.&lt;/p&gt;

&lt;h2&gt;
  
  
  React
&lt;/h2&gt;

&lt;p&gt;React provides multiple helpers, including &lt;code&gt;ComponentProps&lt;/code&gt;, or the more specific &lt;code&gt;ComponentPropsWithoutRef&lt;/code&gt; if you don't want to accept a &lt;code&gt;ref&lt;/code&gt; prop. They both requires one type parameter which is a string corresponding to an HTML element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ComponentPropsWithoutRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;specialProp&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;specialProp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Solid
&lt;/h2&gt;

&lt;p&gt;Solid provides similar a helper with its &lt;code&gt;JSX.ComponentProps&lt;/code&gt; type&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ComponentProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;splitProps&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;solidjs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;ComponentProps&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;specialProp&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;others&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;splitProps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;specialProp&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;others&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Svelte
&lt;/h2&gt;

&lt;p&gt;Svelte takes a bit different approach where you can import the direct interface from "svelte/elements" without using a type parameter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- ButtonComponent.svelte --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HTMLButtonAttributes&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;svelte/elements&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;HTMLButtonAttributes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;specialProp&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;specialProp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="nx"&gt;ButtonProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;$props&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;{...&lt;/span&gt;&lt;span class="na"&gt;rest&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Button Text&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Vue
&lt;/h2&gt;

&lt;p&gt;Vue has automatic "fallthrough" attribute, so any prop that you don't explicitly define will automatically get passed through the root element in the template. No Typescript involved!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight vue"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"ts"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineComponent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MyComponent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;customProp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Just need to define the custom prop&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
   &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;script&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!--
   Attributes not matching the `props` object above
   will automatically fall to our button
  --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Button Text&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Learn programming by peeling back layers of abstractions</title>
      <dc:creator>Bao Huynh Lam</dc:creator>
      <pubDate>Wed, 10 Apr 2024 02:35:41 +0000</pubDate>
      <link>https://forem.com/bhuynhdev/learn-programming-by-peeling-back-layers-of-abstractions-211h</link>
      <guid>https://forem.com/bhuynhdev/learn-programming-by-peeling-back-layers-of-abstractions-211h</guid>
      <description>&lt;p&gt;Learn by peeling back layers of abstractions&lt;/p&gt;

&lt;p&gt;Here’s my programming hot take 🌶️: Libraries are amazing, but they might also make you and me “dumber”. Let me explain.&lt;/p&gt;

&lt;p&gt;Preface: Libraries, frameworks, and code sharing in general is absolutely fantastic. The programming world wouldn’t have existed if we weren’t able to utilize other’s well-written and battle-tested code and everyone had to reinvent the wheels every time. Efficiently using the right libraries for the job is one of the best ways to quickly and securely deliver an impactful product.&lt;/p&gt;

&lt;p&gt;However, recently I realized that I have been using so many libraries mindlessly without considering what exactly do they abstract. Some libraries masterfully cover away so many painful complexities that using them feel so easy-breezy that I began to take them for granted.&lt;/p&gt;

&lt;p&gt;And that is dangerous because not always will you have access to these libraries. Companies may have strict permission policies that prevents you from installing certain tools. Moreover, not understanding how the libraries work - what are they good at and what are their shortcoming - hinder my abilities to put them into a bigger picture. When tasked with a similar but more complex situations, I won’t be able to identify and comprehend how a library can help or what are some limitations I need to be aware of. When a new technology revolutionizes the space, I won’t be able to contrast and compare them with each other to recognize why this new thing is so valuable.&lt;/p&gt;

&lt;p&gt;That’s why I have been striving to dig deeper and understand more about the mechanisms at work and let curiosity guide my next journeys. And I definitely encourage everyone, especially beginners to do the same.&lt;/p&gt;

&lt;p&gt;You don’t have to know it all to the tiniest details, but having a general idea how the technology fits into the big picture helps a lot.&lt;/p&gt;

&lt;p&gt;Seek to (and struggle to) learn by peeling back layers of abstractions.&lt;br&gt;
Consider building projects without your favorite libraries.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you have been building in React/Vue/Angular, try building an app with vanilla JavaScript and/or traditional server-rendered templating so as to see what areas JavaScript framework actually helps.&lt;/li&gt;
&lt;li&gt;If you have been using an ORM, try making a small project using raw SQL&lt;/li&gt;
&lt;li&gt;If you have been doing AI with PyTorch and Hugging Face, consider re-building a classic ML architecture using more native technologies (I learned a lot from a school project where we built a simple neural net with just &lt;code&gt;numpy&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Or just start reading, listening, and watching more on the topics of what’s going on under the hood&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have found these basic projects to make me grow a lot by helping me understand what exact "pains" my libraries are abstracting away and help me be less confused about which features are natively-provided vs. library-specific.&lt;/p&gt;

&lt;p&gt;Let me know if you have been doing the same thing to. Would love to hear your success stories!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>Explaining JavaScript Promises with money 💵</title>
      <dc:creator>Bao Huynh Lam</dc:creator>
      <pubDate>Sun, 09 Jul 2023 00:32:57 +0000</pubDate>
      <link>https://forem.com/bhuynhdev/completely-explaining-javascript-promises-using-money-545g</link>
      <guid>https://forem.com/bhuynhdev/completely-explaining-javascript-promises-using-money-545g</guid>
      <description>&lt;h2&gt;
  
  
  What are Promises
&lt;/h2&gt;

&lt;p&gt;JavaScript Promise is similar to how they mean in native English: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A promise/assurance that something will happen in the future, some value will return in the future, but not now&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine you are JavaScript, and your friend &lt;strong&gt;promises&lt;/strong&gt; they will give you $5. You know your friend will give $5 sometime in the future, but not now, so you queue that task back into your memory, and continue doing your thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why do we need Promises anyway?
&lt;/h2&gt;

&lt;p&gt;Promise is part of the non-blocking asynchronous JavaScript workflow. Because JavaScript is single-threaded, we don't want certain actions to block the entire main thread. You don't want data fetching to block rendering the HTML. You don't want submitting requests to a server to pause the GIF playing in the background.&lt;/p&gt;

&lt;p&gt;That's why JavaScript need a way to schedule some tasks that take time to the background and check back on them later, but not now. Prior to Promise, JavaScript uses callbacks, but that leads to huge problems of &lt;strong&gt;&lt;a href="http://callbackhell.com/" rel="noopener noreferrer"&gt;callback hell&lt;/a&gt;&lt;/strong&gt;, so Promise is created as a more ergonomic solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Promises can be a chain
&lt;/h2&gt;

&lt;p&gt;Imagine that immediately after your friend's promise, your mom demands $5 from you. Can you give it to her now? No you can't, because you don't have it, but you can &lt;strong&gt;schedule&lt;/strong&gt; that: wait until after your friend give you $5, then you can give it to your mom. And that's how the Promises chain happens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Friend gives you $5
  &amp;lt;-- Then you give it to mom
  &amp;lt;-- Then your mom praises you
  &amp;lt;-- Then you are happy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that actions that depend on the value of a Promise get chained into a big Promise chain, and the whole thing becomes a big Promise. These scheduled things will happen sometime in the future, but not now. Once you are in Promise land, you can continue the chain, but can't go backout to the synchronous world.&lt;/p&gt;

&lt;h2&gt;
  
  
  Promises can have three states
&lt;/h2&gt;

&lt;p&gt;Note that a Promise can have three states: Pending, Resolved, and Rejected. While waiting, the Promise is pending. If your friend's promise continues smoothly, the $5 is given successfully, then the Promise is resolved. However, if any errors happen in the Promise chain (your friend lost the money to the wind), it becomes Rejected, and will error out.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to work with JS Promise &amp;amp; code samples
&lt;/h2&gt;

&lt;p&gt;You can create a Promise yourself with the Promise constructor, which takes in a function that decide how to resolve or reject the promise.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// If at the time this Promise is invoked, it's Saturday&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;today&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDay&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Happy day&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Then successfully returns string&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Not Saturday&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Else error out&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also quickly create a Promise that automatically resolves with &lt;code&gt;Promise.resolve()&lt;/code&gt;, or a Promise that automatically rejects with &lt;code&gt;Promise.reject()&lt;/code&gt;, which are mostly used for testing purposes.&lt;/p&gt;

&lt;p&gt;Most of the time, you won't need to create a Promise yourself, and instead work with Promises given by other libraries like in &lt;code&gt;fetch&lt;/code&gt;, &lt;code&gt;axios&lt;/code&gt;, or &lt;code&gt;bcrypt&lt;/code&gt;. You can chain any dependent action with &lt;code&gt;.then()&lt;/code&gt;, and catch error with &lt;code&gt;.catch()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Schedule a Fetch promise&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that Promises are queued into the background by JavaScript to be checked back later, so the code below will not work like you expected, as you would be mismatching synchronous code and asynchronous code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
&lt;span class="c1"&gt;// After promise is resolved, `value` will be assigned to `title`&lt;/span&gt;
&lt;span class="c1"&gt;// But for now, JS will queue this task onto the background, and&lt;/span&gt;
&lt;span class="c1"&gt;// continue immediately with the next line&lt;/span&gt;
&lt;span class="nf"&gt;newValuePromise&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Therefore, even if you console.log here, you'd still get `undefined`,&lt;/span&gt;
&lt;span class="c1"&gt;// no matter how fast or instant your Promise is&lt;/span&gt;
&lt;span class="c1"&gt;// Once you are in Promise land, you can continue the chain, but&lt;/span&gt;
&lt;span class="c1"&gt;// can't go back out to the synchronous world.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One thing to watch out for is that only the value you &lt;strong&gt;return&lt;/strong&gt; from the previous &lt;code&gt;.then&lt;/code&gt; is available to the next &lt;code&gt;.then&lt;/code&gt;. If you forgot to return any value, the next &lt;code&gt;.then&lt;/code&gt; won't have it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;upperCaseVal&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;upperCaseVal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Since the previous `.then` only console.log and did not&lt;/span&gt;
    &lt;span class="c1"&gt;// return any value, this `.then` does not have any value    &lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Async and Await
&lt;/h2&gt;

&lt;p&gt;Async/Await is another syntax to work with Promises besides &lt;code&gt;.then()&lt;/code&gt;. If you tag your function with &lt;code&gt;async&lt;/code&gt;, then you use &lt;code&gt;await&lt;/code&gt; instead of &lt;code&gt;.then&lt;/code&gt; to continue the promise chain&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;happy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// If happy response, then add a new diary entry&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;anotherResponse&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://diary.com/new&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;anotherResponse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;anotherResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;normal day&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is equivalent to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handleResponse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;happy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://diaray.com/new&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;anotherResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;anotherResponse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Normal day&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see how async/await really simplify the code flow and nesting, and is much more readable.&lt;/p&gt;

&lt;p&gt;Note that the async function still returns a Promise. In an async function, it might look like you are writing normal synchronous JavaScript, but async/await is just a syntactic sugar over &lt;code&gt;.then()&lt;/code&gt;, and whatever value you return from an async function will be wrapped into a Promise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some random caveats
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;setTimeOut()&lt;/code&gt; is actually not a Promise
&lt;/h3&gt;

&lt;p&gt;You will notice that &lt;code&gt;setTimeOut&lt;/code&gt; is used a lot in an asynchronous settings, either to stimulate Promise taking time in tutorials, or to schedule something that JS will come back to in the future. However, &lt;code&gt;setTimeOut()&lt;/code&gt; actually does not return a Promise itself, and instead works with callback function (old-school style). You can convert &lt;code&gt;setTimeOut()&lt;/code&gt; to a &lt;code&gt;sleep()&lt;/code&gt; function that returns a Promise like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Making setTimeOut return a resolved Promise after `ms` time&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ms&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Awoken after 1000ms sleep&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Or without async&lt;/span&gt;
&lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Changed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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