<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Yoav Ganbar</title>
    <description>The latest articles on DEV Community by Yoav Ganbar (@hamatoyogi).</description>
    <link>https://dev.to/hamatoyogi</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%2F238398%2Ff21fd0eb-ce0b-4728-8ac6-1d02af1ca073.png</url>
      <title>DEV Community: Yoav Ganbar</title>
      <link>https://dev.to/hamatoyogi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hamatoyogi"/>
    <language>en</language>
    <item>
      <title>Modern CSS for 2024: Nesting, Layers, and Container Queries</title>
      <dc:creator>Yoav Ganbar</dc:creator>
      <pubDate>Thu, 28 Dec 2023 15:29:58 +0000</pubDate>
      <link>https://dev.to/builderio/modern-css-for-2024-nesting-layers-and-container-queries-4c43</link>
      <guid>https://dev.to/builderio/modern-css-for-2024-nesting-layers-and-container-queries-4c43</guid>
      <description>&lt;p&gt;I’ve written before about &lt;a href="https://www.builder.io/blog/css-the-good-parts" rel="noopener noreferrer"&gt;how far CSS has come&lt;/a&gt; and how it has gotten way better in the past few years, as well as shared some &lt;a href="https://www.builder.io/blog/css-tips-for-better-web-development" rel="noopener noreferrer"&gt;tips to level your CSS game&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But this time of year is a great time to have a look at what a banger-year CSS had. Especially with projects like &lt;a href="https://web.dev/blog/interop-2023" rel="noopener noreferrer"&gt;Interop 2023&lt;/a&gt; and &lt;a href="https://github.com/web-platform-dx/web-features/blob/main/docs/baseline.md" rel="noopener noreferrer"&gt;Baseline&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this post, I want to focus on 3 features you can start using today. One will help you deal with legacy projects, the second can clean up your CSS code many folds, and the third will change the way you approach responsive design.&lt;/p&gt;

&lt;p&gt;All of these features are supported in all modern browsers, so there’s no reason to not start using them today!&lt;/p&gt;

&lt;p&gt;Let’s dig in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we'll be working on
&lt;/h2&gt;

&lt;p&gt;To get something done that might be a real-world scenario, we need some design to work with. I’ve randomly selected this notification card from Loom:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F405fcb096417479caba147961c971b6a%3Fwidth%3D800" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F405fcb096417479caba147961c971b6a%3Fwidth%3D800" alt="Untitled" width="800" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve added the design to Figma, as that’s usually where most UI work starts.&lt;/p&gt;

&lt;p&gt;To save time, and not try and recreate this little UI nugget manually, I ran it through Builder’s &lt;a href="https://www.builder.io/m/design-to-code" rel="noopener noreferrer"&gt;Visual Copilot Figma plugin&lt;/a&gt; to make it generate the code for us.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 You can find the &lt;a href="https://codepen.io/hamatoyogi/pen/MWxYjJw" rel="noopener noreferrer"&gt;code in this link&lt;/a&gt;. Also, you can scroll to the last section to see how I generated the code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Less code with native CSS nesting
&lt;/h2&gt;

&lt;p&gt;Notice the initial code above has some duplication for media queries. Some might like to just take out the CSS rules into one media query.&lt;/p&gt;

&lt;p&gt;However, in the age of components, to me, it makes more sense to have each class of styles encapsulate how it should behave in different breakpoints under it.&lt;/p&gt;

&lt;p&gt;Also, it would be nice to groups of children so we don’t need to have to use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Descendant_combinator" rel="noopener noreferrer"&gt;descendant combinators&lt;/a&gt; (&lt;code&gt;.parent .child&lt;/code&gt;) selectors.&lt;/p&gt;

&lt;p&gt;Native &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting" rel="noopener noreferrer"&gt;CSS nesting&lt;/a&gt; is now ready to help with such a task!&lt;/p&gt;

&lt;p&gt;In the past, you’d need to rely on pre-processors such as &lt;a href="https://sass-lang.com/" rel="noopener noreferrer"&gt;SaSS&lt;/a&gt; or &lt;a href="https://lesscss.org/" rel="noopener noreferrer"&gt;Less&lt;/a&gt;, but not anymore… Native CSS nesting has landed on all major modern browsers.&lt;/p&gt;

&lt;p&gt;Here’s how we could refactor the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;article&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"column"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt; &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"img"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"column"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"top"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     Record a loom to add a personal touch to your messages
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bottom"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
     Add a personal touch to your communication by sending a Loom. Discover
     all the ways you can use Loom
     &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      here.
     &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"column"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"rec-btn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Record now&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c"&gt;/* ... styles */&lt;/span&gt;

 &lt;span class="err"&gt;@media&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;767px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* the styles specific for the beakpoint nested under the calss it affects */&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c"&gt;/* ... styles */&lt;/span&gt;

 &lt;span class="c"&gt;/* nested children */&lt;/span&gt;
 &lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="py"&gt;column&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;nth-of-type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;44%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;

 &lt;span class="nc"&gt;.column&lt;/span&gt;&lt;span class="nd"&gt;:first-child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;

 &lt;span class="c"&gt;/* nested media query */&lt;/span&gt;
 &lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;767px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;/* nested child affected by media query */&lt;/span&gt;
  &lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="py"&gt;column&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;nth-of-type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="err"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* ... more styles */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 See the full code in this &lt;a href="https://codepen.io/hamatoyogi/pen/qBvEqez" rel="noopener noreferrer"&gt;Codepen link&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After running a character count (not including white spaces), without nesting I was at 975 characters vs with nesting which ended up being 868 characters (at least according to ChatGPT 😅).&lt;/p&gt;

&lt;p&gt;It might not seem much with this small example but just think about a decent size project and how much less code and less complexity you can get.&lt;/p&gt;

&lt;h3&gt;
  
  
  What you can nest
&lt;/h3&gt;

&lt;p&gt;It’s important to note that besides media queries and children of parents, you can nest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multiple &lt;code&gt;@media&lt;/code&gt; rules&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@layer&lt;/code&gt; (more on that in a bit)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@supports&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@scope&lt;/code&gt; (Currently only works on Chrome)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@container&lt;/code&gt; (more on this below)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  More nesting info
&lt;/h3&gt;

&lt;p&gt;Before we got similar syntax to SaSS and Less styled nesting, native CSS nesting had to be done with an &lt;code&gt;&amp;amp;amp;&lt;/code&gt; character to explicitly state the relationship between parent and style rules.&lt;/p&gt;

&lt;p&gt;Now with general availability in all browsers, you can choose whether to use it or just nest like the good ol’ days. However, it’s important to understand there’s a difference when not using it.&lt;/p&gt;

&lt;p&gt;When using the &lt;code&gt;&amp;amp;amp;&lt;/code&gt; nested child selectors are relative to the parent element. Whereas, not using &lt;code&gt;&amp;amp;amp;&lt;/code&gt; makes you use the child rule selector is the one selecting the elements. That means the child rule selector has the same specificity as using &lt;code&gt;:is()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For a deeper dive into nesting, I recommend going through &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting/Using_CSS_nesting" rel="noopener noreferrer"&gt;the MDN docs&lt;/a&gt;, reading &lt;a href="https://developer.chrome.com/docs/css-ui/css-nesting" rel="noopener noreferrer"&gt;Adam Argyle’s post&lt;/a&gt;, and &lt;a href="https://ishadeed.com/article/css-nesting" rel="noopener noreferrer"&gt;this post by Ahmad Shadeed&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Say Goodbye to &lt;code&gt;!important&lt;/code&gt; with CSS &lt;code&gt;@layer&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The headline is somewhat true. It’s not to say that with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/@layer" rel="noopener noreferrer"&gt;&lt;code&gt;@layer&lt;/code&gt;&lt;/a&gt; you can take a legacy project that is littered with &lt;code&gt;!important&lt;/code&gt; changes one or two things and you’re off to the races, able to change styles with ease and add new things without worrying about breaking the existing styles.&lt;/p&gt;

&lt;p&gt;However, it can come in handy instead of littering your codebase with &lt;code&gt;!important&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The general idea of &lt;code&gt;@layer&lt;/code&gt; is that you can decide on the order of the cascade. In other words, it can help you define the order of precedence in case of the multiple cascade layers.&lt;/p&gt;

&lt;p&gt;Let’s have a look at a simple example to understand the syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.alert&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;brown&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;medium&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;limegreen&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;@layer&lt;/span&gt; &lt;span class="n"&gt;module&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.alert&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;medium&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;violet&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&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;At the top of the file, we declare the layer order. The "state" layer is last and so, it will override the "module" layer. The rest of the code is just the different declarations for each layer.&lt;/p&gt;

&lt;p&gt;So, in essence, we can utilize this to override styles in case of a legacy project, or even use it to apply one-off theming.&lt;/p&gt;

&lt;p&gt;Let’s imagine our notification card from above is inside some sort of legacy project, to which we do have access to the CSS source.&lt;/p&gt;

&lt;p&gt;Let’s also say that we have a new requirement to change the text size of the top section, the text color in the bottom section, and the color of the button.&lt;/p&gt;

&lt;p&gt;What we could do in this case is the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Decide on the cascade layer order */&lt;/span&gt;
&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;legacy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;/* Add a "new" layer with the overrides we want */&lt;/span&gt;
&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nc"&gt;.text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;.top&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.bottom&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rebeccapurple&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="nc"&gt;.rec-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;hotpink&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* wrap the legacy code with the layer name "legacy" */&lt;/span&gt;
&lt;span class="k"&gt;@layer&lt;/span&gt; &lt;span class="n"&gt;legacy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c"&gt;/* same code as before  */&lt;/span&gt;
 &lt;span class="c"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty nice, no?&lt;/p&gt;

&lt;p&gt;We used both nesting and layers. In the past, to achieve this we would have had to either fight with specificity or add a new stylesheet and make heavy use of &lt;code&gt;!important&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;a href="https://codepen.io/hamatoyogi/pen/mdoyWgv" rel="noopener noreferrer"&gt;Codepen link.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Bye-bye media queries, hello container queries
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_container_queries#naming_containment_contexts" rel="noopener noreferrer"&gt;CSS Container Queries&lt;/a&gt; are a game-changer in the world of responsive design, stepping beyond the limitations of traditional media queries.&lt;/p&gt;

&lt;p&gt;Unlike media queries that base responsiveness on the viewport size, container queries allow styling based on the size of a parent container. This shift empowers developers to create more modular, reusable components that adapt seamlessly within different container contexts. &lt;br&gt;&lt;/p&gt;



&lt;p&gt;The benefits are clear: enhanced layout control improved component-based responsiveness, and simplified, cleaner CSS.&lt;/p&gt;

&lt;p&gt;For instance, let’s take the use of our notification card example code. Using container queries, we can remove almost all of our media queries and dictate what needs to change if the card's width is below our threshold (692px which we arbitrarily decided, is the max-width for our card):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c"&gt;/* define the container type */&lt;/span&gt;
 &lt;span class="py"&gt;container-type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;inline-size&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="c"&gt;/* name the container (optional) */&lt;/span&gt;
 &lt;span class="py"&gt;container-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;notification-card&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;16px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;108&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;102&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;133&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;692px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

 &lt;span class="c"&gt;/* This media query was kept as you can't target the element which is the container */&lt;/span&gt;
 &lt;span class="err"&gt;@media&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;767px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* ... rest of the code is the same, only media queries removed from classes */&lt;/span&gt;

&lt;span class="c"&gt;/* what changes once the container is below our threshold */&lt;/span&gt;
&lt;span class="k"&gt;@container&lt;/span&gt; &lt;span class="n"&gt;notification-card&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;692px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nc"&gt;.content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;/* we can use nesting as well */&lt;/span&gt;
  &lt;span class="err"&gt;.column&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nc"&gt;.column&lt;/span&gt;&lt;span class="nd"&gt;:nth-of-type&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="nc"&gt;.img&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="nc"&gt;.text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;.rec-btn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 &lt;a href="https://codepen.io/hamatoyogi/pen/eYXmVKV?editors=1100" rel="noopener noreferrer"&gt;Codepen example&lt;/a&gt;.&lt;br&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this example, &lt;code&gt;.wrapper&lt;/code&gt; becomes a container, and we can target its child elements to adapt their layout based on the card's width, not the viewport. I don’t know about you, but to me this feels more in line with modern, component-based web development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contain yourself
&lt;/h3&gt;

&lt;p&gt;Of course, there are more things to know. For example, there are more keywords we can use besides &lt;code&gt;(width &amp;amp;lt; {value})&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For different logic, we can use the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;and&lt;/code&gt; - allows combining 2 or more conditions (&lt;code&gt;@container (width &amp;amp;gt; 400px) and (height &amp;amp;gt; 400px)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;or&lt;/code&gt; - like &lt;code&gt;and&lt;/code&gt; can be used to combine conditions that apply when one is true. (&lt;code&gt;@container (width &amp;amp;gt; 400px) or (height &amp;amp;gt; 400px)&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;not&lt;/code&gt; - as the name suggests, negates the condition. Allowed only one time per query and can’t be used in combination with &lt;code&gt;and&lt;/code&gt; or &lt;code&gt;or&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other than logical keywords, you can use different descriptors other than &lt;code&gt;width&lt;/code&gt;, such as &lt;code&gt;aspect-ratio&lt;/code&gt;, &lt;code&gt;block-size&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, &lt;code&gt;inline-size&lt;/code&gt; or &lt;code&gt;orientation&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are also special &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_container_queries#container_query_length_units" rel="noopener noreferrer"&gt;container query length units&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How we generated the HTML + CSS
&lt;/h2&gt;

&lt;p&gt;All it took was a few simple steps, that can be seeing in this video:&lt;/p&gt;


  


&lt;blockquote&gt;
&lt;p&gt;💡 You can check out the initial output &lt;a href="https://codepen.io/hamatoyogi/pen/MWxYjJw" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Granted, it’s not perfect on the first go, but it was something to start with. We were able to &lt;a href="https://www.builder.io/blog/convert-figma-to-html" rel="noopener noreferrer"&gt;convert Figma to HTML in just one click&lt;/a&gt;, how cool is that?!&lt;/p&gt;

&lt;p&gt;After that, I copied it to &lt;a href="http://Codepen.io" rel="noopener noreferrer"&gt;Codepen.io&lt;/a&gt;, and tweaked it.&lt;/p&gt;

&lt;p&gt;Visual Copilot automatically made all the code responsive, but it has made some weird assumptions and class naming here and there, (this is using the free “fast” code generation, which is getting better every day 🙂, and using the “quality” tab yields better results).&lt;/p&gt;

&lt;p&gt;After that I’ve made a few changes like better class names, semantic tags, and fixed some responsive issues (you can see the cleaned up code in &lt;a href="https://codepen.io/hamatoyogi/pen/jOJEMBg?editors=1100" rel="noopener noreferrer"&gt;this Codepen link&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There you have it, 3 new CSS features to start using in the new year.&lt;/p&gt;

&lt;p&gt;CSS has truly transformed into a mighty tool in the web dev arsenal, especially with these killer features.&lt;/p&gt;

&lt;p&gt;Embracing the power of native CSS nesting and &lt;code&gt;@layer&lt;/code&gt; can produce smarter, cleaner style sheets.&lt;/p&gt;

&lt;p&gt;But the real showstopper? CSS Container Queries. They're rewriting the rules of responsive design, making our lives as devs a whole lot easier. No more wrestling with media queries for every little tweak. Just set your container's size and watch as your components adapt like magic.&lt;/p&gt;

&lt;p&gt;It's not just about writing less code; it's about writing smarter, more efficient code.&lt;/p&gt;

&lt;p&gt;The future of web design is looking pretty darn exciting, and we're just getting started! 🚀💻🎨&lt;/p&gt;

&lt;p&gt;What do you say? Would you start using these in your projects?&lt;/p&gt;


  


&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fa59bf5c79450490387c6ffe5914637d6%3Fwidth%3D389" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fa59bf5c79450490387c6ffe5914637d6%3Fwidth%3D389" width="389" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fec73bc7266784389afd672007bfbdc94%3Fwidth%3D308" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fec73bc7266784389afd672007bfbdc94%3Fwidth%3D308" width="308" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Introducing Visual Copilot: a new AI model to convert Figma designs to high quality code in a click.&lt;br&gt;&lt;/p&gt;



&lt;p&gt;No setup needed. 100% free. Supports all popular frameworks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://builder.io/signup" rel="noopener noreferrer"&gt;Try Visual Copilot&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Astro + Qwik: Houston, we have Resumability!</title>
      <dc:creator>Yoav Ganbar</dc:creator>
      <pubDate>Wed, 20 Dec 2023 15:19:41 +0000</pubDate>
      <link>https://dev.to/builderio/astro-qwik-houston-we-have-resumability-om0</link>
      <guid>https://dev.to/builderio/astro-qwik-houston-we-have-resumability-om0</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Originally written by &lt;a href="https://twitter.com/TheJackShelton" rel="noopener noreferrer"&gt;Jack Shelton&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hey Devs! My name is &lt;a href="https://twitter.com/TheJackShelton" rel="noopener noreferrer"&gt;Jack&lt;/a&gt;, and I am a freelance fullstack developer based in Texas. I also work on this thing called &lt;a href="https://qwikui.com/" rel="noopener noreferrer"&gt;Qwik UI&lt;/a&gt; in my free time. 🙂&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;In mid-late 2022, I had the opportunity to try &lt;a href="https://astro.build/" rel="noopener noreferrer"&gt;Astro&lt;/a&gt;, a server-first, content-focused, and extremely flexible meta-framework on my day job.&lt;/p&gt;

&lt;p&gt;It quickly became my go-to for creating landing pages, marketing websites, and even small web apps. If my clients needed something, it was almost always a click and integration guide away.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fed9d96db1222462b89baf4f03e80617e%3Fwidth%3D707" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fed9d96db1222462b89baf4f03e80617e%3Fwidth%3D707" alt="An image of a rocket on a notebook in space." width="707" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Astro sites significantly outperformed the previous static site generators I had used. I appreciated the speed and found it intuitive to work with.&lt;/p&gt;

&lt;p&gt;Unfortunately, as I added more interactivity, my Astro sites began to slow down, despite Astro being the fastest meta-framework I had used up to that point!&lt;/p&gt;

&lt;p&gt;My clients and I took notice of this. I spent a lot of time researching how to improve site speed, but in the end it always felt like an uphill battle of optimizing versus adding the stuff my clients needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The journey
&lt;/h2&gt;

&lt;p&gt;In an ideal world, you could build your application, and it would be extremely fast, regardless of the level of interactivity or the size of your page. This appears to be an unsolvable problem. The more components we add, the slower it gets.&lt;/p&gt;

&lt;p&gt;I wondered, did it have to be this way? Is it even possible to have a fast and easy development process? Is it the &lt;a href="https://www.builder.io/blog/dont-blame-the-developer-for-what-the-frameworks-did" rel="noopener noreferrer"&gt;developer’s fault&lt;/a&gt; when our apps are slow?&lt;/p&gt;

&lt;p&gt;Looking back, I’d say no! Developers should focus on what matters most: building the product! So, how do we solve this issue? For a while, it was a big what if. 😅&lt;/p&gt;

&lt;p&gt;That what if quickly became a reality when I discovered Qwik’s &lt;a href="https://www.builder.io/blog/resumability-from-ground-up" rel="noopener noreferrer"&gt;resumability&lt;/a&gt;. I was 100% certain it was exactly what I was looking for.&lt;/p&gt;

&lt;p&gt;So I did some research. I saw a lot of comparisons between the two in terms of performance. April this year I thought “why don’t we use them together?” One is a meta-framework, and the other a UI framework.&lt;/p&gt;

&lt;p&gt;Would it still be resumable?&lt;/p&gt;

&lt;p&gt;Is Astro’s partial hydration approach going to be a problem with a framework that doesn’t have &lt;a href="https://www.builder.io/blog/hydration-is-pure-overhead" rel="noopener noreferrer"&gt;hydration&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;How would it work with islands?&lt;/p&gt;

&lt;p&gt;Well, turns out I wasn’t the only one!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F988e08cd27f34323b77b937432ed88d5%3Fwidth%3D707" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F988e08cd27f34323b77b937432ed88d5%3Fwidth%3D707" alt="A screenshot of a Discord chat between Misko and Jack." width="707" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After some awesome help from Misko, creator of Angular and Qwik, as well as the Astro core team, I can finally answer that question I had back in April.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing @qwikdev/astro:
&lt;/h2&gt;

&lt;p&gt;Astro’s first resumable UI framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  Starts fast, stays fast
&lt;/h3&gt;

&lt;p&gt;One of Astro's key features is &lt;strong&gt;Zero JS, by default&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Unfortunately, this is usually not the case after adding a JavaScript framework and any subsequent components.&lt;/p&gt;

&lt;p&gt;If we want to introduce interactivity with a framework, such as React, Vue, Svelte, and so on, the framework runtime is then introduced. The number of components added to the page also increases linearly O(n) with the amount of JavaScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding Qwik
&lt;/h3&gt;

&lt;p&gt;Qwik builds on top of Astro's &lt;strong&gt;Zero JS, by default&lt;/strong&gt; principle and then some. Thanks to resumability, the components are not executed unless resumed. Even with interactivity, the framework is also not executed until it needs to be. &lt;a href="https://www.builder.io/blog/our-current-frameworks-are-on-we-need-o1" rel="noopener noreferrer"&gt;It is O(1) constant&lt;/a&gt;, … with zero effort on the developer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F41f896cda32b43279d7c32ee6725c79f%3Fwidth%3D707" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F41f896cda32b43279d7c32ee6725c79f%3Fwidth%3D707" alt="An Illustration of hydration vs resumability." width="707" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This integration for Astro enables resumability, fine-grained lazy loading, and many of the Qwik core stuff we know and love.&lt;/p&gt;

&lt;p&gt;This includes all of the Astro goodies, like view transitions, MDX collections, and the hundreds of integrations that Astro provides.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So where would @qwikdev/astro make sense?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can use it anywhere you’re currently using a framework component in Astro! Using Qwik and resumability should significantly speed up your site.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do Qwik components need hydration directives?
&lt;/h3&gt;

&lt;p&gt;Short answer, no!&lt;/p&gt;

&lt;p&gt;In other UI frameworks, a hydration directive, such as &lt;code&gt;client:only&lt;/code&gt; or &lt;code&gt;client:load&lt;/code&gt;, would be needed for interactivity. However, these are not needed with Qwik because there is no hydration!&lt;/p&gt;

&lt;p&gt;When using Qwik inside a meta-framework like Astro or Qwik City, components are loaded on the server, prefetched in a separate thread, and "resumed" on the client.&lt;/p&gt;

&lt;p&gt;For example, here's how we use a Qwik counter component in Astro.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;counter.tsx&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;component$&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useSignal&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;@builder.io/qwik&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;counter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useSignal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;counter&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;++&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;index.astro&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="o"&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;Counter&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;../components/counter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;---&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Astro&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;Qwik&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="cm"&gt;/* no hydration directive! */&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/body&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/html&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Does resumability work?
&lt;/h3&gt;

&lt;p&gt;Yes! We can lazily execute code on interaction, just like using Qwik with Qwik City.&lt;/p&gt;


      
    

&lt;p&gt;Here, we are refreshing the page, and you'll notice that nothing was executed until the button was clicked. Without resumability, our `` component would have been executed on page load.&lt;/p&gt;

&lt;p&gt;The 402 byte q-chunk is our Counter's &lt;code&gt;onClick$&lt;/code&gt; handler.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's in that 17.61kb chunk?
&lt;/h3&gt;

&lt;p&gt;That's the framework! We do not execute it until it is needed. In this case, it is gzipped using SSG.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How about islands?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of islands, we have Qwik containers! These fit quite well into Astro’s island model, having similar limitations.&lt;/p&gt;

&lt;p&gt;Below is an example of a Qwik container in Astro. In the DOM, you'll notice there aren't any `` custom elements. This is because, to Astro, Qwik appears as static data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F1f8b5720be2b4157a614b754abd8f041%3Fwidth%3D707" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F1f8b5720be2b4157a614b754abd8f041%3Fwidth%3D707" alt="Untitled" width="707" height="157"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is just the beginning! You can try out the integration in Alpha today, by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx astro add @qwikdev/astro
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 This integration is currently in Alpha release. We encourage you to try it and share your feedback. If you run into any problems, open up an issue in our &lt;a href="https://github.com/QwikDev/astro/issues" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can also view the package on &lt;a href="https://www.npmjs.com/package/@qwikdev/astro" rel="noopener noreferrer"&gt;NPM&lt;/a&gt;, &lt;a href="https://github.com/QwikDev/astro" rel="noopener noreferrer"&gt;Github&lt;/a&gt;, &lt;a href="https://qwik.builder.io/docs/integrations/astro/" rel="noopener noreferrer"&gt;Qwik integration page&lt;/a&gt;, and the &lt;a href="https://astro.build/integrations/?search=qwik" rel="noopener noreferrer"&gt;Astro integration page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Join the fun and &lt;a href="https://github.com/QwikDev/astro/blob/main/contributing.md" rel="noopener noreferrer"&gt;contribute&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Stay awesome devs,&lt;/p&gt;

&lt;p&gt;-Jack&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Tip: Visit our &lt;a href="https://www.builder.io/m/qwik-cms" rel="noopener noreferrer"&gt;Qwik hub&lt;/a&gt; to learn more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;br&gt;
      &lt;br&gt;
     &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fa59bf5c79450490387c6ffe5914637d6%3Fwidth%3D389" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fa59bf5c79450490387c6ffe5914637d6%3Fwidth%3D389" width="389" height="180"&gt;&lt;/a&gt; &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fec73bc7266784389afd672007bfbdc94%3Fwidth%3D308" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fec73bc7266784389afd672007bfbdc94%3Fwidth%3D308" width="308" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Introducing Visual Copilot: a new AI model to convert Figma designs to high quality code in a click.  &lt;/p&gt;

&lt;p&gt;No setup needed. 100% free. Supports all popular frameworks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://builder.io/signup" rel="noopener noreferrer"&gt;Try Visual Copilot&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;em&gt;Read the &lt;a href="https://www.builder.io/blog/astro-qwik" rel="noopener noreferrer"&gt;full post&lt;/a&gt; on the &lt;a href="https://www.builder.io/blog" rel="noopener noreferrer"&gt;Builder.io blog&lt;/a&gt;&lt;/em&gt;
&lt;/h5&gt;

</description>
      <category>webdev</category>
      <category>astro</category>
      <category>qwik</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Bun vs Node.js: Everything you need to know</title>
      <dc:creator>Yoav Ganbar</dc:creator>
      <pubDate>Thu, 21 Sep 2023 15:01:06 +0000</pubDate>
      <link>https://dev.to/builderio/bun-vs-nodejs-everything-you-need-to-know-4l66</link>
      <guid>https://dev.to/builderio/bun-vs-nodejs-everything-you-need-to-know-4l66</guid>
      <description>&lt;p&gt;&lt;em&gt;Written by &lt;a href="https://twitter.com/CodevolutionWeb" rel="noopener noreferrer"&gt;Vishwas Gopinath&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On September 8th, there was fresh buzz in the JavaScript community: Bun v1.0, created by &lt;a href="https://twitter.com/jarredsumner" rel="noopener noreferrer"&gt;Jarred Sumner&lt;/a&gt;, had arrived. But with all the talk, many are left wondering: What's the essence of Bun? Why is everyone drawing parallels with the tried-and-true &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;? Is Bun just another fleeting trend, or is it here to redefine the game? In this article, let’s dive deep into Bun, check out its features, and find out how it compares to the well-established Node.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is Bun?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Bun is a super fast all-in-one toolkit for JavaScript and TypeScript apps. The beauty of Bun lies in its ability to streamline the development process, making it smoother and more efficient than ever. This is possible because Bun is not just a runtime, it's also a package manager, a bundler, and a test runner. Imagine having a Swiss Army knife for JS development; that's Bun for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What Bun solves for&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The inception of Node.js in 2009 was groundbreaking. However, as with many technologies, as it grew, so did its complexity. Think of it like a city. As a city expands, traffic congestion can become a problem.&lt;/p&gt;

&lt;p&gt;Bun aims to be the new infrastructure that alleviates this congestion, making things run smoother and faster. It's not about reinventing the wheel but refining it, ensuring that while we get the speed and simplicity, we don't lose the essence of what makes JavaScript unique and powerful.&lt;/p&gt;

&lt;p&gt;Bun is designed as a faster, leaner, more modern replacement for Node.js so let’s take a closer look at some comparison. But first let’s discuss one other topic.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Node.js versus Deno versus Bun&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When discussing the evolution of JavaScript runtimes, it's hard to overlook &lt;a href="https://deno.com/" rel="noopener noreferrer"&gt;Deno&lt;/a&gt;. Ryan Dahl, the creator of Node.js, introduced Deno as a new runtime that aimed to address some of the challenges and regrets he identified with Node.js.&lt;/p&gt;

&lt;p&gt;Deno is a secure runtime for JavaScript and TypeScript. It directly addresses many of the shortcomings of Node.js. For instance, Deno natively supports TypeScript without the need for external tools. Unlike Node.js, where scripts have broad permissions by default, Deno adopts a security-first approach requiring developers to explicitly grant permissions for potentially sensitive operations, such as file system access or network connectivity.&lt;/p&gt;

&lt;p&gt;While Deno presents a compelling alternative to Node.js, it hasn't matched Node.js's widespread adoption. Therefore, this article centers on contrasting Bun with the well-established Node.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Getting started&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With Bun, we can scaffold an empty project with the command &lt;code&gt;bun init -y&lt;/code&gt;. We have a few files generated and in index.ts, add a line, &lt;code&gt;console.log("Hello, Bun!")&lt;/code&gt;. In the terminal, run the command &lt;code&gt;bun index.ts&lt;/code&gt; to see “Hello, Bun!” logged.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Bun versus Node.js: JavaScript runtime&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A JavaScript runtime is an environment which provides all the necessary components in order to use and run a JavaScript program.&lt;/p&gt;

&lt;p&gt;Both Node.js and Bun are runtimes. Node.js is primarily written in C++ where as Bun is written with a low-level general purpose programming language called &lt;a href="https://ziglang.org/" rel="noopener noreferrer"&gt;Zig&lt;/a&gt;. But that is just the tip of the ice berg. Let’s take a closer look at other differences when treating Bun as a runtime alone.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;JavaScript engine&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A JavaScript engine is a program that converts JavaScript code we write into machine code that allows a computer to perform specific tasks.&lt;/p&gt;

&lt;p&gt;While Node.js uses Google's &lt;a href="https://v8.dev/" rel="noopener noreferrer"&gt;V8 engine&lt;/a&gt; that power's Chrome browser, Bun uses &lt;a href="https://developer.apple.com/documentation/javascriptcore" rel="noopener noreferrer"&gt;JavaScriptCore&lt;/a&gt; (JSC), which is an open source JavaScript engine developed by Apple for Safari.&lt;/p&gt;

&lt;p&gt;V8 and JSC have different architectures and optimization strategies. JSC prioritizes faster start times and reduced memory usage with a slightly slower execution time. On the other hand, V8 prioritizes fast execution with more runtime optimization which may lead to more memory usage.&lt;/p&gt;

&lt;p&gt;This makes Bun fast, starting up to 4x faster than Node.js.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fffa01b170c5e450e9a9f8e1e347e39a6%3Fwidth%3D742" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fffa01b170c5e450e9a9f8e1e347e39a6%3Fwidth%3D742" alt="Summary: bun ran 2.19 times faster than deno and 4.81 times faster than node" width="742" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Summary: bun ran 2.19 times faster than deno and 4.81 times faster than node&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Transpiler&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;While Node.js is a powerful runtime for JavaScript, it doesn't natively support TypeScript files. To execute TypeScript in a Node.js environment, external dependencies are required. One common approach is to use a build step to transpile TypeScript (TS) into JavaScript (JS) and then run the resulting JS code. Here's a basic setup that uses the &lt;code&gt;ts-node&lt;/code&gt; package:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Installation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; typescript ts-node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Script configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;package.json&lt;/code&gt;, you can set up scripts to streamline the process:&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="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scripts&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ts-node ./path/to/your/file.ts&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;&lt;strong&gt;3. Execution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With the above script, you can easily run your TypeScript file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In contrast, Bun offers a more streamlined approach. It comes with a JavaScript transpiler integrated into the runtime. This allows you to directly run .&lt;code&gt;js, .ts, .jsx&lt;/code&gt;and &lt;code&gt;.tsx&lt;/code&gt; files. Bun's built-in transpiler seamlessly converts these files to vanilla JavaScript, facilitating immediate execution without additional steps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference in speed is magnified when running a TypeScript file as Node.js requires a transpilation step before it can be run.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fa929240bcfb647f7b019075de9d6f9b9%3Fwidth%3D742" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fa929240bcfb647f7b019075de9d6f9b9%3Fwidth%3D742" alt="Bun takes 8ms, Node esbuild 40ms, tsx 120ms and tsx 350ms" width="742" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;ESM and CommonJS compatibility&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A module system allows developers to organize code into reusable segments. In JavaScript, the two primary module systems are &lt;a href="https://nodejs.org/api/modules.html#modules-commonjs-modules" rel="noopener noreferrer"&gt;CommonJS&lt;/a&gt; and &lt;a href="https://nodejs.org/api/esm.html#modules-ecmascript-modules" rel="noopener noreferrer"&gt;ES modules&lt;/a&gt; (ESM). CommonJS, originating from Node.js, uses &lt;code&gt;require&lt;/code&gt; and &lt;code&gt;module.exports&lt;/code&gt; for synchronous module handling, ideal for server-side operations.&lt;/p&gt;

&lt;p&gt;ESM, introduced in ES6, employs &lt;code&gt;import&lt;/code&gt; and &lt;code&gt;export&lt;/code&gt; statements, providing a more static and asynchronous approach, optimized for browsers and modern build tools. Let's use &lt;code&gt;colors&lt;/code&gt; for CommonJS and &lt;code&gt;chalk&lt;/code&gt; for ESM, two popular packages for adding colored outputs to the console and to better understand the module systems.&lt;/p&gt;

&lt;p&gt;Node.js has been traditionally associated with the CommonJS module system. Here's a typical usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// CommonJS in Node.js (index.js)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;colors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;colors&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;colors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;green&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello, world!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For ES modules in Node.js, you have one of two options:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You need to include &lt;code&gt;"type": "module"&lt;/code&gt; in your &lt;code&gt;package.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use the &lt;code&gt;.mjs&lt;/code&gt; extension.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ESM in Node.js (index.mjs)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;chalk&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;chalk&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;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello, world!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The transition from CommonJS to ES modules (ESM) has been a complex journey. It took Node.js half a decade post ESM's introduction to support it without the experimental flag. Still, CommonJS remains prevalent in the ecosystem.&lt;/p&gt;

&lt;p&gt;Bun simplifies the module system by supporting both without any special configuration. Bun's standout feature is its ability to support both &lt;code&gt;import&lt;/code&gt; and &lt;code&gt;require()&lt;/code&gt; in the same file, something not natively possible in Node.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Mixed modules in Bun (index.js)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;chalk&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;chalk&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;colors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;colors&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;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;magenta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from chalk!&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;colors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cyan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from colors!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Web APIs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Web APIs, integral to browser-based applications, offer tools like &lt;code&gt;fetch&lt;/code&gt; and &lt;code&gt;WebSocket&lt;/code&gt; for web interactions. While these have become browser standards, their support in server-side environments like Node.js has been inconsistent.&lt;/p&gt;

&lt;p&gt;In earlier versions of Node.js, Web standard APIs commonly available in browsers weren't natively supported. Developers had to rely on third-party packages like &lt;code&gt;node-fetch&lt;/code&gt; to replicate this functionality. However, from Node.js v18, there's experimental support for the &lt;code&gt;fetch&lt;/code&gt; API, potentially eliminating the need for these packages.&lt;/p&gt;

&lt;p&gt;Bun simplifies this by offering built-in support for these Web standard APIs. Developers can directly use stable &lt;code&gt;fetch&lt;/code&gt;, &lt;code&gt;Request&lt;/code&gt;, &lt;code&gt;Response&lt;/code&gt;, &lt;code&gt;WebSocket&lt;/code&gt; and other browser-like APIs without any additional packages. Furthermore, Bun's native implementation of these Web APIs ensures they are faster and more reliable compared to third-party alternatives.&lt;/p&gt;

&lt;p&gt;Here's an example compatible with both Node.js (v18 and above) and Bun. While it's experimental in Node.js, the same functionality is stable in Bun:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Experiment fetch in Node.js (v18 and above) and built-in fetch in Bun&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;fetchUserData&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://jsonplaceholder.typicode.com/users/1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="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;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;fetchUserData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Leanne Graham&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Hot reloading&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Hot reloading is a feature that boosts developer productivity by automatically refreshing or reloading parts of an application in real-time as the code changes, without requiring a full restart.&lt;/p&gt;

&lt;p&gt;In the Node.js ecosystem, you have a couple of options for achieving hot reloading. One popular tool has been &lt;code&gt;nodemon&lt;/code&gt;, which hard-restarts the entire process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nodemon index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, starting from Node.js v18, there's an experimental &lt;code&gt;--watch&lt;/code&gt; flag introduced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--watch&lt;/span&gt; index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both methods aim to provide real-time reloading of the application as code changes. However, they might have different behaviors, especially in certain environments or scenarios.&lt;/p&gt;

&lt;p&gt;For instance, &lt;code&gt;nodemon&lt;/code&gt; can lead to disruptions like disconnecting HTTP and WebSocket connections, while the &lt;code&gt;--watch&lt;/code&gt; flag, being experimental, might not offer the full suite of features and has some reported issues in the &lt;a href="https://github.com/nodejs/node/issues?q=--watch" rel="noopener noreferrer"&gt;GitHub issues&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Bun takes hot reloading a step further. By running Bun with the &lt;code&gt;--hot&lt;/code&gt; flag, hot reloading is enabled:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun &lt;span class="nt"&gt;--hot&lt;/span&gt; index.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike the Node.js methods that might require a full process restart, Bun reloads your code in-place without terminating the old process. This ensures that HTTP and WebSocket connections remain uninterrupted and the application state is preserved, providing a smoother development experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Node.js compatibility&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;When transitioning to a new runtime or environment, compatibility is often a primary concern for developers. Bun addresses this by positioning itself as a drop-in replacement for Node.js. This means that existing Node.js applications and npm packages can seamlessly integrate with Bun without any modifications. Key features that ensure this compatibility include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support for built-in Node.js modules such as &lt;code&gt;fs&lt;/code&gt;, &lt;code&gt;path&lt;/code&gt;, and &lt;code&gt;net&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Recognition of global variables like &lt;code&gt;__dirname&lt;/code&gt; and &lt;code&gt;process&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Adherence to the Node.js module resolution algorithm, including the familiar &lt;code&gt;node_modules&lt;/code&gt; structure.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bun is still evolving. It's tailored to enhance development workflows and is ideal for environments where resources are limited, such as serverless functions. The team behind Bun is striving for comprehensive Node.js compatibility and better integration with prevalent frameworks&lt;/p&gt;

&lt;p&gt;While Bun ensures compatibility with Node.js, it doesn't stop there. Bun ships with highly-optimized, standard-library APIs for the things you need most as a developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Bun APIs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Bun.file()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lazily load files and access their content in various formats. This method is up to 10x faster than its Node.js counterpart.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bun (index.ts)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Bun&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;package.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Node.js (index.mjs)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs/promises&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fileContents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;package.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Bun.write()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A versatile API to write data to disk, from strings to Blobs. It writes up to 3x faster than Node.js.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bun (index.ts)&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Bun&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;html/&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Node.js (index.mjs)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fs/promises&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;html/&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Bun.serve()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Set up HTTP server or WebSocket server using Web-standard APIs. It can serve 4x more requests per second than Node.js and handle 5x more WebSocket messages than the &lt;code&gt;ws&lt;/code&gt; package in Node.js. This backend capability is reminiscent of how developers use Express in Node.js but with the added benefits of Bun's performance optimizations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bun (index.ts)&lt;/span&gt;
&lt;span class="nx"&gt;Bun&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;serve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3000&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="nx"&gt;request&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;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello from Bun!&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="c1"&gt;// Node.js (index.mjs)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;http&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;http&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeHead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&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="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/plain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello from Node.js!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bun also has support for sqlite and password built-in.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Bun versus Node.js: package manager&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Bun is more than just a runtime; it's an advanced toolkit that includes a powerful package manager. If you've ever found yourself patiently waiting during dependency installations, Bun offers a refreshingly faster alternative. Even if you don't use Bun as a runtime, its built-in package manager can speed up your development workflow.&lt;/p&gt;

&lt;p&gt;Check out this table comparing Bun commands with &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;npm&lt;/a&gt;, Node's package manager:&lt;/p&gt;

&lt;p&gt;At a glance, Bun's commands might seem familiar but the experience is anything but ordinary. Bun boasts installation speeds that are orders of magnitude faster than npm. It achieves this by leveraging a global module cache, eliminating redundant downloads from the npm registry. Additionally, Bun employs the fastest system calls available for each operating system, ensuring optimal performance.&lt;/p&gt;

&lt;p&gt;Here's a speed comparison of installing dependencies for a starter Remix project from cache, comparing Bun and npm:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F68bfdc8b5baa41dba053822bca1ff1f7%3Fwidth%3D742" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F68bfdc8b5baa41dba053822bca1ff1f7%3Fwidth%3D742" alt="Bun takes 0.36s, pnpm 6.44s, npm 10.58s and yarn 12.08s" width="742" height="367"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;bun&lt;/code&gt; CLI contains a Node.js-compatible package manager designed to be a dramatically faster replacement for &lt;code&gt;npm&lt;/code&gt;, &lt;code&gt;yarn&lt;/code&gt;, and &lt;code&gt;pnpm&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Moreover, a &lt;code&gt;bun run &amp;lt;command&amp;gt;&lt;/code&gt; takes just 7ms, while &lt;code&gt;npm run &amp;lt;command&amp;gt;&lt;/code&gt; takes 176ms. While Node.js's npm has been the standard for JavaScript package management for years, Bun really is a speed powerhouse and presents a compelling alternative.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Bun versus Node.js: bundler&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Bundling is the process of taking multiple JavaScript files and merging them into one or more optimized bundles. This process can also involve transformations, such as converting TypeScript to JavaScript or minifying the code to reduce its size.&lt;/p&gt;

&lt;p&gt;In the Node.js ecosystem, bundling is typically handled by third-party tools rather than Node.js itself. Some of the most popular bundlers in the Node.js world include &lt;a href="https://webpack.js.org/" rel="noopener noreferrer"&gt;Webpack&lt;/a&gt;, &lt;a href="https://rollupjs.org/" rel="noopener noreferrer"&gt;Rollup&lt;/a&gt;, and &lt;a href="https://parceljs.org/" rel="noopener noreferrer"&gt;Parcel&lt;/a&gt;, offering features like &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Code_splitting" rel="noopener noreferrer"&gt;code splitting&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Tree_shaking" rel="noopener noreferrer"&gt;tree shaking&lt;/a&gt;, and &lt;a href="https://webpack.js.org/concepts/hot-module-replacement/" rel="noopener noreferrer"&gt;hot module replacement&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Bun, on the other hand, is not just a runtime and a package manager but also a bundler in its own right. It's designed to bundle JavaScript and TypeScript code for various platforms, including frontend applications in the browser (React or Next.js applications) and Node.js.&lt;/p&gt;

&lt;p&gt;To bundle with Bun, you can use a simple command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun build ./index.ts &lt;span class="nt"&gt;--outdir&lt;/span&gt; ./build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command bundles the &lt;code&gt;index.ts&lt;/code&gt; file and outputs the result in the &lt;code&gt;./build&lt;/code&gt; directory. The bundling process is incredibly fast, with Bun being 1.75x faster than esbuild, and significantly outpacing other bundlers like Parcel and Webpack.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fd43dc089058a4b448de3c189ed20cbf6%3Fwidth%3D742" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fd43dc089058a4b448de3c189ed20cbf6%3Fwidth%3D742" alt="Bun takes 0.17s, esbuild 0.3s, rspack 4.45s, Parcel 2 26.32s, Rollup 32s and Webpack 5 38.02s" width="742" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bun takes 0.17s, esbuild 0.3s, rspack 4.45s, Parcel 2 26.32s, Rollup 32s and Webpack 5 38.02s&lt;/p&gt;

&lt;p&gt;A standout feature in Bun is its introduction of JavaScript macros. These allow for the execution of JavaScript functions during bundling, with the results directly inlined into the final bundle. This mechanism offers a fresh perspective on bundling.&lt;/p&gt;

&lt;p&gt;Check out this example where Bun's JavaScript macros are leveraged to fetch a username during the bundling process. Instead of making a runtime API call, the macro fetches the data at bundle-time, inlining the result directly into the final output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// users.ts&lt;/span&gt;

&lt;span class="k"&gt;export&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;getUsername&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://jsonplaceholder.typicode.com/users/1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// index.ts&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;getUsername&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;./users.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;macro&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;username&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;getUsername&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// build/index.js&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Leanne Graham&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;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While Node.js has its established bundling tools, Bun offers an integrated, faster, and innovative alternative that could reshape the bundling landscape.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Bun versus Node.js: test runner&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Testing is a crucial aspect of software development, which ensures that code behaves as expected and catches potential issues before they reach production. In addition to being a runtime, a package manager and a bundler, Bun is also a test runner.&lt;/p&gt;

&lt;p&gt;While Node.js developers have traditionally relied on &lt;a href="https://jestjs.io/" rel="noopener noreferrer"&gt;Jest&lt;/a&gt; for their testing needs, Bun introduces a built-in test runner that promises speed, compatibility, and a range of features that cater to modern development workflows.&lt;/p&gt;

&lt;p&gt;Bun's test runner, &lt;code&gt;bun:test&lt;/code&gt;, is designed to be fully compatible with Jest, a testing framework known for its "expect"-style APIs. This compatibility ensures that developers familiar with Jest can easily transition to Bun without a steep learning curve.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expect&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;bun:test&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2 + 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executing tests is straightforward with the &lt;code&gt;bun test&lt;/code&gt; command. Moreover, Bun's runtime supports TypeScript and JSX out of the box, eliminating the need for additional configurations or plugins.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Migrating from Jest or Vitest&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Bun's commitment to compatibility shines through its support for Jest's global imports. For instance, importing from &lt;code&gt;@jest/globals&lt;/code&gt; or &lt;code&gt;vitest&lt;/code&gt; will be internally re-mapped to &lt;code&gt;bun:test&lt;/code&gt;. This means that existing test suites can run on Bun without any code modifications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.test.ts&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;test&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;@jest/globals&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;test suite&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;addition&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Performance benchmarks&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Bun's test runner is not just about compatibility; it's about speed. In a benchmark against the test suite for &lt;a href="https://zod.dev/" rel="noopener noreferrer"&gt;Zod&lt;/a&gt;, Bun proved to be 13x faster than Jest and 8x faster than Vitest. This speed advantage is further highlighted by Bun's matchers, which are implemented in fast native code. For instance, &lt;code&gt;expect().toEqual()&lt;/code&gt; in Bun is a staggering 100x faster than Jest and 10x faster than Vitest.&lt;/p&gt;

&lt;p&gt;Whether you're looking to migrate existing tests or start a new project, Bun provides a robust testing environment that aligns with modern development needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Node.js has long been a cornerstone in the JavaScript world, setting benchmarks and guiding developers. However, Bun is stepping onto the scene as a noteworthy challenger, pushing boundaries.&lt;/p&gt;

&lt;p&gt;While it's still early days for Bun, the buzz it's generating is undeniable. Currently, it's optimized for MacOS and Linux, and while Windows support is in progress, some features are still on the horizon. With all it offers, Bun is certainly a toolkit you should consider exploring.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" width="405" height="143"&gt;&lt;/a&gt;&lt;/p&gt;


      
    

&lt;p&gt;Visually build with your components&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;Builder.io&lt;/a&gt; is a visual editor that connects to any site or app and lets you &lt;a href="https://www.builder.io/m/products" rel="noopener noreferrer"&gt;drag and drop&lt;/a&gt; with &lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;your components&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://builder.io/signup" rel="noopener noreferrer"&gt;Try it out&lt;/a&gt; &lt;a href="https://dev.to/m/developers"&gt;Learn more&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Dynamically render your components&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;MyPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="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;BuilderComponent&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;registerComponents&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;MyHero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyProducts&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  &lt;em&gt;Read the &lt;a href="https://www.builder.io/blog/bun-vs-node-js" rel="noopener noreferrer"&gt;full post&lt;/a&gt; on the &lt;a href="https://www.builder.io/blog" rel="noopener noreferrer"&gt;Builder.io blog&lt;/a&gt;&lt;/em&gt;
&lt;/h5&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>bunjs</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A First Look at HTMX and How it Compares to React</title>
      <dc:creator>Yoav Ganbar</dc:creator>
      <pubDate>Mon, 18 Sep 2023 20:33:22 +0000</pubDate>
      <link>https://dev.to/builderio/a-first-look-at-htmx-and-how-it-compares-to-react-4jdl</link>
      <guid>https://dev.to/builderio/a-first-look-at-htmx-and-how-it-compares-to-react-4jdl</guid>
      <description>&lt;p&gt;For a while now, we've had heavyweights like &lt;a href="https://reactjs.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;React&lt;/strong&gt;&lt;/a&gt; taking center stage in the world of dynamic web apps. While they're powerful, sometimes they can feel like overkill, especially if you're more of a backend champ navigating the frontend labyrinth.&lt;/p&gt;

&lt;p&gt;Now, there’s a fresh perspective on the block: &lt;a href="https://htmx.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;HTMX&lt;/strong&gt;&lt;/a&gt;. It gracefully bridges that space between classic server-side rendering and today's client-side interactivity. No need to juggle a ton of JavaScript; HTMX has got you.&lt;/p&gt;

&lt;p&gt;Curious about HTMX? In this article, we’ll unpack its features, the advantages it offers, and see how it sizes up against the well-known development giants. Let’s get into it!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Web dev's wild ride&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Once upon a time, web pages were just static displays. You wanted a change? Update that HTML by hand. But the web's appetite grew, craving more action, more interaction. &lt;strong&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript" rel="noopener noreferrer"&gt;JavaScript&lt;/a&gt;&lt;/strong&gt; entered the game, turning pages into lively stages.&lt;/p&gt;

&lt;p&gt;Fast forward to the AJAX game-changer in the 2000s. No more full page reloads – it was all about that sleek, seamless vibe. And &lt;strong&gt;&lt;a href="https://jquery.com/" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt;&lt;/strong&gt;? It made AJAX cool and way more developer-friendly.&lt;/p&gt;

&lt;p&gt;Next chapter: Frameworks. &lt;strong&gt;&lt;a href="https://reactjs.org/" rel="noopener noreferrer"&gt;React&lt;/a&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;a href="https://vuejs.org/" rel="noopener noreferrer"&gt;Vue&lt;/a&gt;&lt;/strong&gt;, and &lt;strong&gt;&lt;a href="https://angular.io/" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;&lt;/strong&gt; stepped in, bringing structure but also, well, some brain-teasers for the backend folks.&lt;/p&gt;

&lt;p&gt;Today? Tools like HTMX hint at a new era. They're asking, "Why not mix the best of both worlds?" Dynamic and sleek, but without the heavyweight lifting. Just check the buzz from &lt;strong&gt;&lt;a href="https://www.youtube.com/watch?v=3GObi93tjZI&amp;amp;list=PLY_che_OEsX3eIKKLUKvQXfVJhCHYWATM&amp;amp;index=21&amp;amp;t=13s" rel="noopener noreferrer"&gt;DjangoCon 2022&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;HTMX explained&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The heartbeat&lt;/strong&gt; : What's HTMX's jam? Keeping things simple. Dive deep into web wizardry without ditching your good ol' HTML. It spices up HTML, sprinkling attributes that unleash dynamism without you diving deep into JavaScript jungles. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The magic&lt;/strong&gt; : No separate script spells here. HTMX tosses custom attributes into your regular HTML tags. User taps a button? Boom, those attributes whisper AJAX-like requests. Servers hit back, and HTMX refreshes that content, smooth and easy. Logic's chilling server-side, giving client-side scripting a lil' break. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plays well with others&lt;/strong&gt; : And get this, HTMX buddies up with your go-to tech. Rocking with &lt;a href="https://www.djangoproject.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Django&lt;/strong&gt;&lt;/a&gt; or vibing with &lt;a href="https://flask.palletsprojects.com/en/2.0.x/" rel="noopener noreferrer"&gt;&lt;strong&gt;Flask&lt;/strong&gt;&lt;/a&gt;? HTMX slips right in, boosting your game without a total remodel. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lean &amp;amp; mean&lt;/strong&gt; : In a universe where chunky frontend giants rule, HTMX steps up as the slick alternative. It's not here to boot out the big guns like &lt;a href="https://reactjs.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;React&lt;/strong&gt;&lt;/a&gt; or &lt;a href="https://vuejs.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;Vue&lt;/strong&gt;&lt;/a&gt;. It's that streamlined choice when the heavyweights might just be a bit much. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/r-GSGH2RxJs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;HTMX: rethinking interactivity&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When HTMX comes into play, the dynamic of web interactivity shifts. It's about delivering function without the heavy pull of typical JavaScript setups.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Dynamic content on-the-go&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As users navigate content, HTMX ensures a seamless feed without reloading the entire page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
  &lt;span class="na"&gt;hx-get=&lt;/span&gt;&lt;span class="s"&gt;"/more-content"&lt;/span&gt;
  &lt;span class="na"&gt;hx-trigger=&lt;/span&gt;&lt;span class="s"&gt;"revealed"&lt;/span&gt;
  &lt;span class="na"&gt;hx-indicator=&lt;/span&gt;&lt;span class="s"&gt;"#loadingIndicator"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Starting Content
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"loadingIndicator"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Fetching...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Behind-the-scenes form submissions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Forms operate in the backdrop, updating just the specific parts of the page that matter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;hx-post=&lt;/span&gt;&lt;span class="s"&gt;"/submit-form"&lt;/span&gt; &lt;span class="na"&gt;hx-swap=&lt;/span&gt;&lt;span class="s"&gt;"outerHTML"&lt;/span&gt; &lt;span class="na"&gt;hx-target=&lt;/span&gt;&lt;span class="s"&gt;"#formResponse"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"data"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Send&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"formResponse"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Here's the response.&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Auto updates&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Things like live score updates? HTMX handles them, no manual refreshes required.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;hx-get=&lt;/span&gt;&lt;span class="s"&gt;"/latest-scores"&lt;/span&gt; &lt;span class="na"&gt;hx-trigger=&lt;/span&gt;&lt;span class="s"&gt;"every 10s"&lt;/span&gt; &lt;span class="na"&gt;hx-target=&lt;/span&gt;&lt;span class="s"&gt;"#scoreDisplay"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"scoreDisplay"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Starting Score&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Managing UI elements&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;UI components, including pop-up modals, are effortlessly controlled.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;hx-get=&lt;/span&gt;&lt;span class="s"&gt;"/modal-content"&lt;/span&gt; &lt;span class="na"&gt;hx-swap=&lt;/span&gt;&lt;span class="s"&gt;"afterend"&lt;/span&gt; &lt;span class="na"&gt;hx-target=&lt;/span&gt;&lt;span class="s"&gt;"#modalContainer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Show Modal
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"modalContainer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Syncing with server logic&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Operations like adding to a cart align smoothly with server-side actions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;hx-post=&lt;/span&gt;&lt;span class="s"&gt;"/add-to-cart"&lt;/span&gt; &lt;span class="na"&gt;hx-swap=&lt;/span&gt;&lt;span class="s"&gt;"outerHTML"&lt;/span&gt; &lt;span class="na"&gt;hx-target=&lt;/span&gt;&lt;span class="s"&gt;"#cartStatus"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Add Item
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"cartStatus"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Added to cart.&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From these examples, it's clear: HTMX offers a streamlined approach. Melding perfectly with server-side mechanics and minimizing the dense client-side scripts.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The technical stuff: how HTMX works&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Understanding the mechanics of HTMX is crucial for developers looking to harness its full potential. While its syntax is reminiscent of standard HTML, the underlying processes are what set HTMX apart.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Extending HTML&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;At its core, HTMX is about extending HTML's capabilities. It introduces new attributes that, when added to standard HTML tags, enable dynamic behaviors without the need for additional scripts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;hx-get=&lt;/span&gt;&lt;span class="s"&gt;"/update-content"&lt;/span&gt; &lt;span class="na"&gt;hx-trigger=&lt;/span&gt;&lt;span class="s"&gt;"click"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Click to Update Content
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Server communication&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;HTMX seamlessly communicates with the server. When an event specified by &lt;code&gt;hx-trigger&lt;/code&gt; occurs, HTMX makes an AJAX request. The server processes this request and sends back a response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;hx-post=&lt;/span&gt;&lt;span class="s"&gt;"/submit-data"&lt;/span&gt; &lt;span class="na"&gt;hx-trigger=&lt;/span&gt;&lt;span class="s"&gt;"click"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Submit Data
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Swapping content&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One of HTMX's standout features is its ability to swap content on the page based on the server's response. The &lt;code&gt;hx-swap&lt;/code&gt; attribute dictates how this content replacement occurs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;hx-get=&lt;/span&gt;&lt;span class="s"&gt;"/fetch-data"&lt;/span&gt; &lt;span class="na"&gt;hx-trigger=&lt;/span&gt;&lt;span class="s"&gt;"load"&lt;/span&gt; &lt;span class="na"&gt;hx-swap=&lt;/span&gt;&lt;span class="s"&gt;"innerHTML"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Data will load here on page load.
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Handling events&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;HTMX provides a robust event system. Developers can listen for specific events, such as &lt;code&gt;htmx:afterSwap&lt;/code&gt;, to execute custom logic after HTMX has updated content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;htmx:afterSwap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content has been swapped!&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;h3&gt;
  
  
  &lt;strong&gt;Integration with CSS&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;HTMX works seamlessly with CSS. For instance, developers can use the &lt;code&gt;hx-indicator&lt;/code&gt; attribute to display a loading spinner, leveraging CSS animations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;hx-get=&lt;/span&gt;&lt;span class="s"&gt;"/load-content"&lt;/span&gt; &lt;span class="na"&gt;hx-trigger=&lt;/span&gt;&lt;span class="s"&gt;"click"&lt;/span&gt; &lt;span class="na"&gt;hx-indicator=&lt;/span&gt;&lt;span class="s"&gt;"#spinner"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Click to Load
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"spinner"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"hidden"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Loading...
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Error handling&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;In the event of an error, such as a failed AJAX request, HTMX provides mechanisms to handle these gracefully, ensuring a smooth user experience.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;hx-get=&lt;/span&gt;&lt;span class="s"&gt;"/fetch-data"&lt;/span&gt; 
     &lt;span class="na"&gt;hx-trigger=&lt;/span&gt;&lt;span class="s"&gt;"load"&lt;/span&gt; 
     &lt;span class="na"&gt;hx-swap=&lt;/span&gt;&lt;span class="s"&gt;"innerHTML"&lt;/span&gt; 
     &lt;span class="na"&gt;hx-swap-oob=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Data will load here.
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By offering a blend of familiar HTML syntax with powerful dynamic capabilities, HTMX simplifies the process of creating interactive web applications. It bridges the gap between frontend and back-end development, allowing for rich user experiences without the complexities of traditional frameworks.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Benefits of adopting HTMX&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Simplicity and learning curve&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unlike comprehensive frontend frameworks that come with a steep learning curve, HTMX offers a more straightforward approach. By extending HTML, it provides a familiar environment for developers, making it easier to get started.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;hx-get=&lt;/span&gt;&lt;span class="s"&gt;"/load-content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Simple HTMX Example&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Performance gains&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;HTMX's lightweight nature means faster page loads. Without the overhead of loading extensive JavaScript libraries or frameworks, users experience quicker interactions and reduced latency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Reduced Client-Side Complexity&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By shifting much of the dynamic behavior to server-side logic, HTMX reduces the complexity on the client side. This results in cleaner, more maintainable code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Seamless integration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;HTMX is designed to integrate smoothly with existing technologies. Whether you're working with server-side frameworks or databases, HTMX can fit right in without the need for major overhauls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Enhanced user experience&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With its ability to update content dynamically without full page reloads, HTMX ensures a smoother user experience. Transitions are seamless, and users aren't disrupted by jarring page refreshes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Cost-efficient development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Given its simplicity and reduced reliance on extensive frontend development, projects using HTMX can often be completed faster, leading to cost savings in development time and resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Empowerment for backend developers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Backend developers can now play a more active role in crafting the user interface. With HTMX, they can build interactive UI components without diving deep into frontend scripting.&lt;/p&gt;

&lt;p&gt;In a world where efficiency, performance, and user experience are paramount, HTMX emerges as a compelling choice for web developers. It offers a balanced blend of power and simplicity, making it a valuable tool in modern web development.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;HTMX vs. React: a comparative analysis&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In the realm of web development, tools and frameworks are often weighed against each other to determine their strengths, weaknesses, and best use cases. As React is currently the reigning king of frontend, it’s expected one would compare HTMX and &lt;a href="https://reactjs.org/" rel="noopener noreferrer"&gt;React&lt;/a&gt;. While they serve similar end goals of creating dynamic web applications, their approaches are different.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/wIzwyyHolRs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Philosophy and Approach&lt;/strong&gt; :
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTMX&lt;/strong&gt; : It extends HTML, allowing developers to add interactivity directly within the markup. The focus is on simplicity and leveraging server-side logic.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;hx-get=&lt;/span&gt;&lt;span class="s"&gt;"/dynamic-content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Load Content with HTMX&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; : A JavaScript library for building user interfaces, React emphasizes component-based architecture and a virtual DOM for efficient updates.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Learning curve&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTMX&lt;/strong&gt; : With its HTML-centric approach, HTMX offers a gentler learning curve, especially for those familiar with traditional web development.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; : While powerful, React comes with its own set of concepts like JSX, state, and props, which can be overwhelming for newcomers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Performance&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTMX&lt;/strong&gt; : Being lightweight, HTMX ensures faster initial page loads and reduced client-side processing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; : Thanks to its virtual DOM, React can efficiently update the UI, making it suitable for large-scale applications with frequent updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Integration&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTMX&lt;/strong&gt; : Designed to work seamlessly with existing server-side technologies, making it a plug-and-play solution for many projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; : While versatile, integrating React might require additional configurations, especially in projects not built around a JavaScript ecosystem.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Use cases&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTMX&lt;/strong&gt; : Best suited for projects that require dynamic interactivity without the overhead of a full-fledged frontend framework. It's also ideal for backend developers looking to add interactivity without extensive JavaScript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; : Perfect for single-page applications (SPAs) and projects that demand a rich, interactive user experience with complex state management.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Community and ecosystem&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTMX&lt;/strong&gt; : While growing in popularity, its community is smaller compared to established frameworks. However, the quality of support and resources is commendable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt; : Boasts a vast community, a plethora of third-party libraries, and extensive resources, making it a go-to choice for many developers worldwide.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Drawbacks and tradeoffs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Nothing is sunshine and rainbows, and obviously, there are tradeoffs to any tool you use. Below are some things that are important to take into account, and just know, before going all in.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The approach is not new, essentially a variation of &lt;a href="https://knockoutjs.com/" rel="noopener noreferrer"&gt;Knockout&lt;/a&gt;, &lt;a href="https://alpinejs.dev/" rel="noopener noreferrer"&gt;Alpine&lt;/a&gt;, and similar "JS-in-HTML" approaches.&lt;/li&gt;
&lt;li&gt;Limited Domain Specific Language (&lt;a href="https://en.wikipedia.org/wiki/Domain-specific_language" rel="noopener noreferrer"&gt;DSL&lt;/a&gt;) makes it less convenient — lacks features like syntax highlighting, linting, and static analysis.&lt;/li&gt;
&lt;li&gt;No type safety.&lt;/li&gt;
&lt;li&gt;Debugging can be challenging for the same reasons.&lt;/li&gt;
&lt;li&gt;Bottom line, this approach is really only good for smaller projects where you need just a touch of JavaScript. We've been down this road before with vanilla and jQuery years ago, and we moved on for solid reasons.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both HTMX and React have their merits. The choice between them boils down to the project's requirements, the team's familiarity with the tools, and the desired development experience. While React remains a dominant force in the frontend world, HTMX is carving its niche, offering a simpler, yet powerful alternative.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/DuGyH5RvfbY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;HTMX's role in upcoming web development&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;HTMX is gaining traction in web development, and here's a glance at its potential impact:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Blending old and new&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;HTMX offers a balance, merging server-side rendering's reliability with the zest of modern client-side interactions. It's an appealing solution for dynamic yet efficient web projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Inclusive development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not all developers delve deeply into frontend complexities. HTMX provides a platform where backend-focused individuals can also design interactive web pages without wrestling with dense JavaScript frameworks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Prioritizing performance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With online users valuing speed, HTMX's streamlined approach promotes the development of swift and agile web platforms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Adapting to fresh trends&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The web world is ever-evolving. HTMX's adaptable design means it's poised to mesh well with emerging technologies and standards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Possible shift in approach&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The growing interest in HTMX suggests a potential evolution in web development methods. While substantial frontend frameworks have their place, simpler, efficient tools are gaining momentum.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Community expansion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As HTMX garners more followers, its community will naturally grow. This paves the way for additional resources, extensions, and collaborations, enhancing its utility in web development.&lt;/p&gt;

&lt;p&gt;In summary, HTMX presents a promising avenue in the realm of web development. It resonates with current developer needs, providing an innovative way to design interactive websites. Its future influence will largely depend on the evolving community and their inventive applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Key takeaways&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In a constantly changing web development landscape, HTMX has its own lane. It enhances HTML, giving developers a familiar setting and making it easier to dive into web interactivity.&lt;/p&gt;

&lt;p&gt;At a time when a web page's speed can define its user experience, HTMX shines with its lightweight nature, ensuring quick loads and silky interactions. It also empowers backend developers, letting them dive deeper into frontend play, bridging the often vast chasm between server logic and client dynamics.&lt;/p&gt;

&lt;p&gt;While the frontend world seems captivated by giants like React and Vue, HTMX brings a refreshing take. It challenges the common belief that you need heaps of JavaScript for a dynamic web app, showing there's another path forward.&lt;/p&gt;

&lt;p&gt;HTMX might be more than just the latest tool on the block. It hints at a possible evolution in how we think about web development, highlighting the delicate balance between tech intricacies and user experience. As its community grows and more adopt it, who knows where HTMX might lead the future narrative of web development?&lt;/p&gt;

&lt;p&gt;One thing for sure is that their &lt;a href="https://twitter.com/htmx_org" rel="noopener noreferrer"&gt;Twitter (X) account&lt;/a&gt; has got some serious meme game... &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F9fcf966a044d4a3ab8ef0e1eb0d7208a%3Fwidth%3D742" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F9fcf966a044d4a3ab8ef0e1eb0d7208a%3Fwidth%3D742" width="601" height="802"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;We've been working on something...&lt;/p&gt;

&lt;p&gt;Don't miss our &lt;a href="https://velocity.builder.io/" rel="noopener noreferrer"&gt;AI launch event&lt;/a&gt; on Oct. 12 &lt;/p&gt;

&lt;p&gt;&lt;a href="https://velocity.builder.io/" rel="noopener noreferrer"&gt;Claim your ticket&lt;/a&gt;&lt;/p&gt;


      
    

&lt;h5&gt;
  
  
  &lt;em&gt;Read the &lt;a href="https://www.builder.io/blog/htmx-vs-react" rel="noopener noreferrer"&gt;full post&lt;/a&gt; on the &lt;a href="https://www.builder.io/blog" rel="noopener noreferrer"&gt;Builder.io blog&lt;/a&gt;&lt;/em&gt;
&lt;/h5&gt;

</description>
      <category>webdev</category>
      <category>frontend</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Finding the Best React CMS: A Comprehensive Guide</title>
      <dc:creator>Yoav Ganbar</dc:creator>
      <pubDate>Sun, 10 Sep 2023 13:12:05 +0000</pubDate>
      <link>https://dev.to/builderio/finding-the-best-react-cms-a-comprehensive-guide-450k</link>
      <guid>https://dev.to/builderio/finding-the-best-react-cms-a-comprehensive-guide-450k</guid>
      <description>&lt;p&gt;Last updated: September 6, 2023&lt;/p&gt;

&lt;p&gt;Choosing the right tools for a React project can be a daunting task, especially when it comes to managing content. Whether you're building a simple blog, an ecommerce app, or a complex enterprise solution, the right Content Management System (CMS) can make or break your project. A CMS not only streamlines the development process but also enhances collaboration, flexibility, and scalability.&lt;/p&gt;

&lt;p&gt;But with so many options available, how do you choose the best CMS for your React project? In this guide, we'll explore the benefits of integrating a &lt;a href="https://www.builder.io/m/react" rel="noopener noreferrer"&gt;CMS with React&lt;/a&gt;, provide you with the insights you need to make an informed decision and outline the process of integrating a React app with a headless CMS.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is React?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://react.dev/" rel="noopener noreferrer"&gt;React&lt;/a&gt; is an open-source JavaScript library for building user interfaces. It offers a declarative approach, simplifying UI creation through efficient virtual DOM utilization. With a component-based architecture, developers create encapsulated and reusable components for intricate user interfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is a CMS?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A content management system (CMS) is a software platform that enables users to create, edit, organize, and publish digital content, such as articles, images, videos and more. Importantly, a CMS allows you to change content on your website without having to make changes in the application code or any other underlying codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;React and CMS: an analogy&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;React&lt;/strong&gt; is like a team of skilled craftsmen who intuitively understand your vision. You don't need to instruct them on every nail and screw; you just describe the desired outcome, and they bring it to life with precision. Similarly, developers use React in a declarative manner (via JSX) to specify what the web application interface should look like, and React ensures it's rendered seamlessly.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;CMS&lt;/strong&gt; is like a curated furniture and décor boutique. You can pick ready-made furniture and decorations to fill your rooms. Yet, the beauty of a CMS is that it allows you to modify or reconfigure your interiors independently, without needing the expertise of the craftsmen who originally constructed the space.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Understanding the headless CMS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A headless CMS is a content management system that decouples the content creation and presentation layers. Unlike traditional CMS platforms, a headless CMS does not enforce a specific front-end (the "head") for displaying content.&lt;/p&gt;

&lt;p&gt;Instead, it provides APIs (Application Programming Interfaces) that help developers fetch from a single content source and deliver data to any desired front-end, such as single page applications, websites, mobile apps, IoT devices, and more, often leveraging CDNs for faster content delivery.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fc9556ccace174d9893c1e76e6c2dc3b8%3Fwidth%3D705" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fc9556ccace174d9893c1e76e6c2dc3b8%3Fwidth%3D705" alt="Comparative architecture diagram: Traditional CMS in a locked container with Admin UI featuring WYSIWYG editor, third-party integrations, content, and frontend app blocks. Headless CMS with minimal data editor, custom APIs, and third-party integrations, connected to a Swift app, a Next.js website, and a Kotlin mobile app via one-sided arrows." width="705" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;📖 Explore our &lt;a href="https://www.builder.io/m/headless-cms-visual-guide" rel="noopener noreferrer"&gt;visual guide on the concept of a headless CMS&lt;/a&gt; for a deeper understanding&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Advantages of a headless CMS with React
&lt;/h2&gt;

&lt;p&gt;In the world of React, a headless CMS is often preferred for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt; : Developers have complete control over the frontend so they can use their preferred tools and frameworks like React, &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;, &lt;a href="https://www.gatsbyjs.com/" rel="noopener noreferrer"&gt;Gatsby&lt;/a&gt;, or &lt;a href="https://remix.run/" rel="noopener noreferrer"&gt;Remix&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-platform support&lt;/strong&gt; : Content can be delivered to websites, mobile apps, and even IoT devices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time updates&lt;/strong&gt; : Changes to content can be reflected in real-time across all platforms to enhance user experiences.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SEO benefits&lt;/strong&gt; : By using a headless CMS with React, developers can optimize the site for search engines to improve visibility and ranking.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Embracing a headless CMS paves the way for React developers to craft more dynamic and adaptive applications. This naturally leads to the question: how do you zero in on the perfect headless CMS for your next project?&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What to consider when choosing a headless CMS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When integrating a headless CMS with your React app, several concerns might arise. Here's an in-depth look at what to consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ease of use&lt;/strong&gt; : How friendly is the CMS for developers? Does it integrate well with popular React or a meta framework like Next.js? Is the documentation clear, and are there tutorials to help you get started?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-device presentation&lt;/strong&gt; : In today's multi-device world, your content must look great everywhere. How easy is it to present the frontend on various devices, including mobile apps, tablets, and desktops? Does the CMS support responsive design and provide tools for testing on different devices?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content team operation&lt;/strong&gt; : Content editors and marketing teams need a system that's intuitive and efficient. Does the CMS offer a friendly editor, templates, and workflows that streamline content creation and publishing? How easy is it for non-technical users to manage content?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration&lt;/strong&gt; : Collaboration is key in modern development. How collaborative is the CMS? Does it offer features like real-time editing, comments, and permissions that facilitate teamwork? Can multiple users work on the same content simultaneously without conflicts?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content localization&lt;/strong&gt; : If your audience is global, content localization is crucial. How supportive is the tool in managing content localization efforts? Does it offer features like multi-language support, currency conversion, and regional customization?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Third-party tool integration&lt;/strong&gt; : Integration with third-party tools can extend the platform's functionality and streamline workflows. How well does the headless CMS handle plugins and third-party tools and solutions? Is there a wide range of available integrations, and how easy is it to develop custom integrations?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Revision history and backups&lt;/strong&gt; : Content changes and updates are inevitable. Does the CMS offer automatic backups and a clear revision history? Can you easily revert to previous versions if needed? How are backups stored and secured?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Guides and docs&lt;/strong&gt; : Comprehensive guides, schema, and docs are essential for both beginners and experts. Are there detailed tutorials, examples, and documentation available? Is there community support through forums, social media, or other channels?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability, performance, scalability, and security&lt;/strong&gt; : These critical areas can make or break your project. How does the CMS perform in terms of reliability, performance, scalability, and security? Are there regular updates, monitoring tools, and support to ensure the system runs smoothly?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customer support&lt;/strong&gt; : What level of customer support is provided? Is there 24/7 support, live chat, email, or phone support? How responsive and knowledgeable is the support team?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Selecting the right headless CMS requires a comprehensive understanding of various factors, from ease of use to customer support. Aligning these considerations with your project's needs will lead to a more streamlined development process. Once you've made the right choice, the next step is understanding how to integrate the CMS into your React application.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Integrating a React app with a headless CMS&lt;/strong&gt;
&lt;/h2&gt;


      
    

&lt;p&gt;Starting a new React app with a headless CMS is a seamless process. Set up a new Next.js app and integrate a headless CMS of your choice. Use the data editor to define your data models and create content entries. Once the content is prepared, publish it. Fetch and render this published data in your Next.js application by consuming the content API from the headless CMS.&lt;/p&gt;

&lt;p&gt;Here's a step-by-step tutorial assuming Next.js as the React framework of choice:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create Next.js app&lt;/strong&gt; : Use the &lt;code&gt;create next app&lt;/code&gt; CLI tool to create a new Next.js project with all the necessary dependencies and configurations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app@latest nextjs-cms-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Integrate headless CMS:&lt;/strong&gt; Choose a headless CMS that suits your needs. Many offer SDKs, templates, and content modeling tools that make integration a breeze.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i your-headless-cms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3.&lt;/strong&gt;  &lt;strong&gt;Creating models and content:&lt;/strong&gt; Define your data models (blueprints) and create content entries (houses). This step involves setting up the structure of your content, defining fields and relationships, as well as validation rules, all of which are stored in a database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.&lt;/strong&gt;  &lt;strong&gt;Publishing:&lt;/strong&gt; Use the CMS's user interface to publish your content. You can schedule content, set up workflows, and collaborate with team members to ensure quality and consistency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.&lt;/strong&gt;  &lt;strong&gt;Connect with frontend:&lt;/strong&gt; Use REST APIs or GraphQL to connect your content with the React components in your app. This step involves mapping your content to the frontend, ensuring a seamless user experience.&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;LandingPage&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;cmsData&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;...//my-cms.com/api/...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cmsData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hero&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cmsData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heroTitle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cmsData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;heroImage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="c1"&gt;// ...rest of the landing page&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6.&lt;/strong&gt;  &lt;strong&gt;Testing and optimization:&lt;/strong&gt; Test your application on various devices, optimize for performance and SEO, and make necessary adjustments to ensure a successful launch.&lt;/p&gt;

&lt;p&gt;While the headless CMS approach offers flexibility and control, there's an evolving trend in the CMS landscape that further empowers both developers and content creators: the visual headless CMS.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Visual headless CMS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A &lt;a href="https://www.builder.io/blog/visual-headless-cms" rel="noopener noreferrer"&gt;visual headless CMS&lt;/a&gt; bridges the gap between the flexibility of a headless CMS and the user-friendly interface of a traditional CMS. This means that while developers enjoy the freedom to design and structure the user interface, content creators and marketers can design, edit, and preview content without the constant need for developer intervention.&lt;/p&gt;

&lt;p&gt;This fusion of features streamlines content creation, offering real-time editing capabilities and clear visualization of content across various platforms. Whether you're a developer, content creator, or marketer, a visual headless CMS provides an enhanced, collaborative approach to digital content management.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Traditional, headless, and visual headless&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Traditional CMS&lt;/strong&gt; platforms like &lt;a href="https://wordpress.com/" rel="noopener noreferrer"&gt;WordPress&lt;/a&gt; offer a straightforward WYSIWYG (What You See Is What You Get) editor. When integrated into code, it typically involves fetching data from the WordPress API and then rendering it directly, often without much flexibility in design or structure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F89e57bf9d75e41fa9ccae09a4ca9db30%3Fwidth%3D705" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F89e57bf9d75e41fa9ccae09a4ca9db30%3Fwidth%3D705" alt="WYSIWYG editor in a traditional CMS" width="701" height="511"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&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;cmsData&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="s1"&gt;...//wordpress.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;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cmsData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="sr"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Headless CMS&lt;/strong&gt; platforms provide a data editor, allowing developers to control rendering. This approach offers more flexibility in terms of UI design and structure, as content is separated from its presentation.&lt;/p&gt;

&lt;p&gt;However, this approach does require more time and effort, as developers need to design schemas, build templates, and wire up APIs to models, among other tasks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Ff9a2ebc35e854187bd3d37e29a3d4c20%3Fwidth%3D705" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Ff9a2ebc35e854187bd3d37e29a3d4c20%3Fwidth%3D705" alt="Simple data editor in a headless CMS" width="705" height="451"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&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;cmsData&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="s1"&gt;...//contentful.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;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cmsData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Hero&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cmsData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cmsData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;     &lt;span class="c1"&gt;// ... other components&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Visual headless CMS&lt;/strong&gt; platforms like &lt;a href="https://www.builder.io/" rel="noopener noreferrer"&gt;Builder.io&lt;/a&gt; combine the best of both worlds. They offer the flexibility of a headless CMS with the visual editing capabilities of a traditional CMS.&lt;/p&gt;

&lt;p&gt;This means content creators can visually design their content while frontend developers maintain control over the structure and rendering. Additionally, the integration process is automated, providing a seamless and enhanced developer experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F7c6b9148c8b54ef4a014cd16c352808f%3Fwidth%3D705" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F7c6b9148c8b54ef4a014cd16c352808f%3Fwidth%3D705" alt="Visual Editor with drag and drop functionality and a Figma like interface in a visual headless CMS" width="705" height="454"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Page&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;cmsData&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="s1"&gt;...//builder.io/...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Header&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cmsData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BuilderComponent&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;cmsData&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;     &lt;span class="c1"&gt;// ... other components with visual editing capabilities&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the code and images, it’s evident that while a traditional CMS offers simplicity and a headless CMS provides flexibility, a visual headless CMS merges these benefits, ensuring a comprehensive content management solution for everyone involved.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Frequently asked questions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Drag and drop capabilities&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.builder.io/blog/nextjs-drag-and-drop" rel="noopener noreferrer"&gt;Is drag-and-drop functionality available in Next.js?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.builder.io/blog/creating-blog" rel="noopener noreferrer"&gt;How can I set up a drag-and-drop blog using a CMS?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.builder.io/blog/drag-drop-react" rel="noopener noreferrer"&gt;Is it possible to drag and drop custom React components within a CMS?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Visual building with Next.js&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.builder.io/blog/visual-next-js" rel="noopener noreferrer"&gt;How can I visually construct pages using Next.js?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Visual editing with CMS&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;﻿&lt;a href="https://www.builder.io/blog/visual-editing-cms" rel="noopener noreferrer"&gt;What methods are available for visual editing in a headless CMS?&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Builder.io Visual Headless CMS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;At &lt;a href="https://www.builder.io" rel="noopener noreferrer"&gt;Builder.io&lt;/a&gt;, we offer a powerful combination of user-friendly visual tools, collaboration-friendly features, and efficient publishing capabilities. We have a &lt;a href="https://chrome.google.com/webstore/detail/builderio/cfldfgibklhmjhnkfighkbafbkbfcmij" rel="noopener noreferrer"&gt;Google Chrome extension&lt;/a&gt; to easily help you with content editing within the web browser, along with a &lt;a href="https://www.figma.com/community/plugin/747985167520967365/Builder.io---Design-to-React-Code-with-AI" rel="noopener noreferrer"&gt;Figma plugin&lt;/a&gt; to make a smoother transition from design to web page. You can incrementally adopt our Visual Headless CMS or rebuild your frontend from scratch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.builder.io/signup" rel="noopener noreferrer"&gt;Get started free&lt;/a&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  &lt;em&gt;Read the &lt;a href="https://www.builder.io/blog/best-react-cms" rel="noopener noreferrer"&gt;full post&lt;/a&gt; on the &lt;a href="https://www.builder.io/blog" rel="noopener noreferrer"&gt;Builder.io blog&lt;/a&gt;&lt;/em&gt;
&lt;/h5&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>cms</category>
      <category>frontend</category>
    </item>
    <item>
      <title>An Overview of 25+ UI Component Libraries in 2023</title>
      <dc:creator>Yoav Ganbar</dc:creator>
      <pubDate>Sun, 10 Sep 2023 05:15:45 +0000</pubDate>
      <link>https://dev.to/builderio/an-overview-of-25-ui-component-libraries-in-2023-51i6</link>
      <guid>https://dev.to/builderio/an-overview-of-25-ui-component-libraries-in-2023-51i6</guid>
      <description>&lt;p&gt;UI component libraries can get you up and running on a new project pretty fast. However, if you’re building a product that has a bespoke design, trying to customize the look and feel of these libraries is a grueling task and might lead to unmaintainable code.&lt;/p&gt;

&lt;p&gt;There are many UI libraries (or, as some call them, UI frameworks) to choose from, and of course, there are different libraries for different front-end frameworks. You might think that coming up on the end of 2023 the industry may have settled on one or two solutions, but it is far from reality.&lt;/p&gt;

&lt;p&gt;The truth is, as with anything in software and the web and something that I say often, that &lt;em&gt;it depends&lt;/em&gt;…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F91fdb36762ad45ea96800ce566fb9996%3Fwidth%3D705" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F91fdb36762ad45ea96800ce566fb9996%3Fwidth%3D705" alt="a screenshot of a post by Ryan Florence." width="705" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The above tweet (X?) by Ryan Florence got me thinking about this subject – not about who is to blame, because that does no good, but more about the reasons why and how we got into this situation.&lt;/p&gt;

&lt;p&gt;In this post, I’m going to give a brief overview of the styling solutions that have led us to the current ecosystem, and we’ll look at some of the more common and popular UI libraries out there.&lt;/p&gt;

&lt;p&gt;(Boot) Strap in, we’re going on a ride.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;History of CSS frameworks and libraries&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Back in the day, web designers were hand-writing CSS, which, trust me, was a journey full of twists (for more on this, see &lt;a href="https://www.builder.io/blog/css-the-good-parts" rel="noopener noreferrer"&gt;CSS The Good Parts&lt;/a&gt;). Then the 2000s hit, bringing with them CSS frameworks like &lt;a href="http://blueprintcss.org/" rel="noopener noreferrer"&gt;Blueprint&lt;/a&gt;, &lt;a href="https://960.gs/" rel="noopener noreferrer"&gt;960 Grid System&lt;/a&gt;, &lt;a href="https://clarle.github.io/yui3/yui/docs/cssgrids/" rel="noopener noreferrer"&gt;YUI Grids&lt;/a&gt;, and &lt;a href="http://www.yaml.de/" rel="noopener noreferrer"&gt;YAML&lt;/a&gt; (probably not the &lt;a href="https://en.wikipedia.org/wiki/YAML" rel="noopener noreferrer"&gt;YAML&lt;/a&gt; you’re thinking of). These frameworks introduced responsive grids and clean UI elements, changing the game.&lt;/p&gt;

&lt;p&gt;Just when we thought we'd seen it all, giants like &lt;a href="https://getbootstrap.com/2.0.2/" rel="noopener noreferrer"&gt;Twitter Bootstrap&lt;/a&gt;, &lt;a href="https://get.foundation/" rel="noopener noreferrer"&gt;Foundation&lt;/a&gt;, and &lt;a href="https://bulma.io/" rel="noopener noreferrer"&gt;Bulma&lt;/a&gt; entered the scene. They made development quick and ensured consistent styling, but the flip side? Websites began feeling a bit too...uniform.&lt;/p&gt;

&lt;p&gt;Recognizing this, the community pivoted, introducing methodologies like &lt;a href="https://getbem.com/" rel="noopener noreferrer"&gt;BEM&lt;/a&gt; to inject some uniqueness and modular style.&lt;/p&gt;

&lt;p&gt;Bottom line? CSS frameworks shifted from solely addressing layout needs to offering comprehensive UI toolkits. But alongside this, methodologies emerged, pushing for more tailored and modular styles.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;JavaScript frameworks changed the game&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With the emergence of JavaScript frameworks such as Angular, React, and Vue, developers needed a more granular approach to correspond with these new component models.&lt;/p&gt;

&lt;p&gt;What is one of CSS’s top features (the “C” in CSS, that is the Cascade) became an issue for these new frameworks.&lt;/p&gt;

&lt;p&gt;As such, a new breed of solution was born — CSS in JS. Mostly prevalent in the React ecosystem, libraries such as &lt;a href="https://styled-components.com/" rel="noopener noreferrer"&gt;Styled Components&lt;/a&gt; and &lt;a href="https://emotion.sh/docs/introduction" rel="noopener noreferrer"&gt;Emotion&lt;/a&gt; allowed scoping styles to components and in so, got rid of the cascade problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Atomic design FTW&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One key concept that got championed by Web Developer and Designer, &lt;a href="https://bradfrost.com/" rel="noopener noreferrer"&gt;Brad Frost&lt;/a&gt;, was “&lt;a href="https://bradfrost.com/blog/post/atomic-web-design/" rel="noopener noreferrer"&gt;atomic design&lt;/a&gt;”.&lt;/p&gt;

&lt;p&gt;The gist of this concept allows developers and designers to think in this new “componentized” world. The idea is that you should think about a component as a sum of atomic design pieces.&lt;/p&gt;

&lt;p&gt;A button, for example, is an atom, a card that holds an image, or some text, and a button - is a molecule. A page, which is consistent with several of these “molecules”, is an organism.&lt;/p&gt;

&lt;p&gt;The culmination of the concept has boiled down to CSS frameworks such as &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 If you want to learn some neat tricks in Tailwind, check out some &lt;a href="https://www.builder.io/blog/tailwind-css-tips-and-tricks" rel="noopener noreferrer"&gt;Tailwind CSS Tips and Tricks Worth Knowing&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The need for a UI framework&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You may ask yourself: “Do I really need a UI framework?” The answer might just be &lt;strong&gt;NO&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Josh Commeau wrote a very good article on the subject titled: “&lt;a href="https://www.smashingmagazine.com/2022/05/you-dont-need-ui-framework/" rel="noopener noreferrer"&gt;You don’t need a UI framework&lt;/a&gt;”.&lt;/p&gt;

&lt;p&gt;Like I’ve said, and I’ll probably keep stating over and over again in any software-related subject - &lt;strong&gt;&lt;em&gt;it depends.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Check out “&lt;a href="https://open.spotify.com/episode/4JD4df5tkGU9yHa3i2MYqU" rel="noopener noreferrer"&gt;Why Do We Need UI Component Libraries? with Alon Valadji&lt;/a&gt;” for a deeper dive.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I once thought that &lt;a href="https://dev.to/hamatoyogi/how-to-build-a-react-ts-tailwind-design-system-1ppi"&gt;building a design system with Styled Components and Tailwind&lt;/a&gt; was the way to go. However, It’s not necessarily the case anymore.&lt;/p&gt;

&lt;p&gt;Nowadays, there are many options that might fit your needs, get you started quicker, perhaps avoid the need for a designer at all, or lay a foundation for a complete bespoke design system.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The broken promise of web components&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;At this point in time, I’d imagine there’d be some sort of Web Component standard that would be usable regardless of your frontend tech stack. However, there’s still no one solution that fits all.&lt;/p&gt;

&lt;p&gt;Web Components were initially introduced with &lt;a href="https://lea.verou.me/blog/2020/09/the-failed-promise-of-web-components/" rel="noopener noreferrer"&gt;the promise of providing a convenient way&lt;/a&gt; to create reusable and customizable HTML elements, developed much faster without waiting for the full spec and implementation process.&lt;/p&gt;

&lt;p&gt;However, they have faced several challenges that have hindered their widespread adoption in UI development. One of the main issues is the complexity introduced by JavaScript frameworks, which has led to overengineered build processes and dependency graphs.&lt;/p&gt;

&lt;p&gt;Additionally, web components have struggled with browser compatibility and standardization. As a result, developers have turned to alternative solutions like React, Angular, and Vue, which offer more straightforward and familiar approaches to building UI components.&lt;/p&gt;

&lt;p&gt;Despite the initial promise, web components have not yet become the go-to solution for UI development that they were once envisioned to be.&lt;/p&gt;

&lt;p&gt;If we can’t use web components, though, what solutions are available to us?&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Types of UI Libraries&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://t3.gg/" rel="noopener noreferrer"&gt;Theo Brown&lt;/a&gt;, a known YouTuber and tech influencer, recently broke down the different types of UI libraries in &lt;a href="https://www.youtube.com/watch?v=CQuTF-bkOgc" rel="noopener noreferrer"&gt;one of his videos&lt;/a&gt;. I think he did quite a good job in categorizing these into these types:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Extensions of CSS:&lt;/strong&gt; for example, &lt;a href="https://sass-lang.com/" rel="noopener noreferrer"&gt;Sass&lt;/a&gt;, &lt;a href="https://lesscss.org/" rel="noopener noreferrer"&gt;Less&lt;/a&gt;, &lt;a href="https://tailwindcss.com/" rel="noopener noreferrer"&gt;Tailwind&lt;/a&gt;, &lt;a href="https://github.com/css-modules/css-modules" rel="noopener noreferrer"&gt;CSS Modules&lt;/a&gt;, to make stuff look a certain way on your own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behavior libraries / Headless:&lt;/strong&gt; for example, &lt;a href="https://headlessui.com/" rel="noopener noreferrer"&gt;HeadlessUI&lt;/a&gt;, &lt;a href="https://www.radix-ui.com/" rel="noopener noreferrer"&gt;Radix&lt;/a&gt;, &lt;a href="https://react-spectrum.adobe.com/react-aria/" rel="noopener noreferrer"&gt;React Aria&lt;/a&gt;, for how things behave, not style.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Style systems:&lt;/strong&gt; such as, &lt;a href="https://tailwindui.com/" rel="noopener noreferrer"&gt;TailwindUI&lt;/a&gt;, &lt;a href="https://daisyui.com/" rel="noopener noreferrer"&gt;DaisyUI&lt;/a&gt;, for a baked-in look and behavior that is up to the developer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Component libraries:&lt;/strong&gt; for example, &lt;a href="https://mui.com/" rel="noopener noreferrer"&gt;MUI&lt;/a&gt;, &lt;a href="https://ant.design/" rel="noopener noreferrer"&gt;Ant Design&lt;/a&gt;, &lt;a href="https://mantine.dev/" rel="noopener noreferrer"&gt;Mantine&lt;/a&gt;, are their own thing. You need to learn how to work with them. (&lt;a href="https://chakra-ui.com/" rel="noopener noreferrer"&gt;ChakraUI&lt;/a&gt;, in Theo’s opinion, is a different beast, sitting somewhere close to “where we want to be”.)
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F55462afc19734652a89e64a7831312cc%3Fwidth%3D705" alt="Venn diagram of different UI library types, taken from YouTube." width="705" height="589"&gt;
## &lt;strong&gt;What makes a good UI library&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here are some key considerations for what makes a good UI framework:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consistency:&lt;/strong&gt; The framework should provide consistent UI elements, patterns, and behaviors across the application. This helps users quickly understand how to use the interface.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility:&lt;/strong&gt; While being consistent, the framework should also allow for customization and extension to fit the specific needs of different applications. Modular and customizable components are ideal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt; The framework should be optimized for performance. Things like file size, render speed, and efficiency matter, especially on mobile.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility:&lt;/strong&gt; Following web accessibility guidelines ensures the framework works for all users. ARIA roles, semantic HTML, and keyboard support are examples.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Documentation:&lt;/strong&gt; Good documentation and examples make the framework easier to learn and implement. API references, style guides, and code samples help speed development.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser Support:&lt;/strong&gt; The framework should work across modern browsers and degrade gracefully in older ones. Progressive enhancement principles apply.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community:&lt;/strong&gt; An active community behind the framework provides discussion forums, plugins, and continued maintenance. This helps sustain long-term viability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intuitive:&lt;/strong&gt; The framework should align with users' mental models and expectations. Leverage natural mappings, consistency, standards, and familiar patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responsive:&lt;/strong&gt; The framework should accommodate diverse screen sizes and input methods. Mobile-first and fluid layouts are best practices here.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In summary, a good UI framework balances consistency and flexibility while optimizing for performance, accessibility, and device support. Great documentation, an active community, and intuitive design are also key. Following established UX principles and heuristics throughout helps ensure quality results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fd09c3d282a984179b2fe12d54622ebc4%3Fwidth%3D705" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fd09c3d282a984179b2fe12d54622ebc4%3Fwidth%3D705" alt="a screenshot of a Cory house post about component libraries on x." width="705" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Popular UI libraries&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;React&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.builder.io/blog/react-js-in-2023" rel="noopener noreferrer"&gt;The React ecosystem&lt;/a&gt; probably has the most UI libraries out there, due to the size of its ecosystem and popularity. As I am more familiar with this world, the list here is longer than other frameworks and is not by any means a complete list of ALL React component libraries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Component libraries:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://mui.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Material UI&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; One of the most popular implementations of &lt;a href="https://m3.material.io/" rel="noopener noreferrer"&gt;Google’s Material Design&lt;/a&gt;. MUI offers a wide range of components, and theming options, and has been around for ages. With that being said, you are bound by their system.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ant.design/" rel="noopener noreferrer"&gt;&lt;strong&gt;Ant Design&lt;/strong&gt;&lt;/a&gt;: A solid option that is been used by a lot of heavy hitters, such as &lt;a href="https://www.tencent.com/en-us/" rel="noopener noreferrer"&gt;Tencent&lt;/a&gt;, &lt;a href="http://www.baidu.com/" rel="noopener noreferrer"&gt;Baidu&lt;/a&gt;, &lt;a href="http://www.alibaba.com/" rel="noopener noreferrer"&gt;AliBaba&lt;/a&gt;, and more. Supports all modern browsers, SSR, &lt;a href="https://nodejs.org/api/esm.html" rel="noopener noreferrer"&gt;esm&lt;/a&gt;, and even &lt;a href="https://www.electronjs.org/" rel="noopener noreferrer"&gt;Electron&lt;/a&gt;. Has also community implementations for &lt;a href="http://ng.ant.design/" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;, &lt;a href="http://antdv.com/" rel="noopener noreferrer"&gt;Vue&lt;/a&gt;, and &lt;a href="https://ant.design/docs/spec/introduce/#front-end-implementation" rel="noopener noreferrer"&gt;more&lt;/a&gt;. Does use CSS-in-JS, so expect runtime overhead as well as AntD ways of doing things.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://chakra-ui.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;ChakraUI&lt;/strong&gt;&lt;/a&gt;: An emphasis on &lt;a href="https://www.a11yproject.com/" rel="noopener noreferrer"&gt;A11y&lt;/a&gt;, meaning it is fully compatible with the WAI-ARIA accessibility standard, has won OSS awards, and has a thriving community. As mentioned, it’s one of the better choices out there as it has a great model for building composable UI, &lt;a href="https://chakra-ui.com/docs/hooks/use-boolean" rel="noopener noreferrer"&gt;built-in hooks&lt;/a&gt;, and great dark-mode support. This is the same team behind &lt;a href="https://zagjs.com/" rel="noopener noreferrer"&gt;Zag.js&lt;/a&gt;, which handles UI as state machines. Once again, you’d need to learn the API, and swapping might be hard to do.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://mantine.dev/" rel="noopener noreferrer"&gt;&lt;strong&gt;Mantine&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; Another fully featured component library with baked in a11y, more than 100 components, and hooks. Mantine is all TypeScript-based and has a way to override default styling. Once more, there’s a lot to learn on how to use its functions and API to achieve your goals.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blueprintjs.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Blueprint&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; A collection of components for building data-intensive interfaces for desktops. It specifically states that it is not designed to work for mobile. It is most likely better for building internal tools, dashboards, and Electron apps. Blueprint is one of the few libs in this list that has a Date Picker component.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://marmelab.com/react-admin/" rel="noopener noreferrer"&gt;&lt;strong&gt;React-Admin&lt;/strong&gt;&lt;/a&gt;: As the name suggests, this component library is targeted at building administrator interfaces for B2B (business-to-business), for example, managing users in your system. It is based on Material design and has a neat feature where you can let it “guess” your list views by providing a sample API endpoint for your data.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://nextui.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;NextUI&lt;/strong&gt;&lt;/a&gt;: Not to be confused with the React meta-framework, &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;, this library is built on top of Tailwind CSS, and claims to have a minimal learning curve. Themes are handled by your &lt;code&gt;tailwind.config.js&lt;/code&gt; file, a11y out of the box, and there’s dark theme support for all components. Overriding styles is done just by putting in different Tailwind class names.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Headless:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://headlessui.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;HeadlessUI&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; The library is only the headless part or behaviors you need to build accessible components. It is specifically designed to integrate with Tailwind, but you could use any CSS solution you like.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://react-spectrum.adobe.com/react-aria/" rel="noopener noreferrer"&gt;&lt;strong&gt;React Aria&lt;/strong&gt;&lt;/a&gt;: A library built by the team at Adobe. It is a full-fledged headless solution that handles behavior, accessibility, and internalization. The API surface of this library is mostly a collection of hooks that you can use (pun intended 😂) to build your components. The pre-defined built components of this lib are currently in alpha.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.radix-ui.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;RadixUI&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; Once only a headless component library, the team recently added themes and some styles. The library’s a11y, and composability features are superb, and I myself have had a great experience with working with it. All themes are exposed via CSS custom properties, which can be easily overridden with CSS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Hybrid approaches:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://ui.shadcn.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;ShadCN/UI&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; A new kid on the block, this library takes a different approach than most of the libraries mentioned here. Instead of &lt;code&gt;npm&lt;/code&gt; installing components or the whole lib and adding it as a dependency, you copy-paste code into your own code base. This is to give you full ownership of the components and separate the design from the implementation. It is built with Tailwind and In order to use this tool, you use the CLI to generate your component code and adjust your &lt;code&gt;tailwind.config.js&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.kuma-ui.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;KumaUI&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; Another relatively new contender, Kuma uses zero runtime CSS-in-JS to create headless UI components which allows a lot of flexibility. It was heavily inspired by other zero runtime CSS-in-JS solutions such as &lt;a href="https://panda-css.com/" rel="noopener noreferrer"&gt;PandaCSS&lt;/a&gt;, &lt;a href="https://vanilla-extract.style/" rel="noopener noreferrer"&gt;Vanilla Extract&lt;/a&gt;, and &lt;a href="https://github.com/callstack/linaria" rel="noopener noreferrer"&gt;Linaria&lt;/a&gt;, as well as by &lt;a href="https://styled-system.com/" rel="noopener noreferrer"&gt;Styled System&lt;/a&gt;, ChakraUI, and &lt;a href="https://nativebase.io/" rel="noopener noreferrer"&gt;Native Base&lt;/a&gt;.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F51c5701bdd30427da983883e6393d9ce%3Fwidth%3D705" alt="a screenshot of a Cory house post about shadcn/ui on x." width="661" height="1500"&gt;
### &lt;strong&gt;﻿Vue&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Being someone who’s a bit unfamiliar with the Vue ecosystem, one thing that I noticed is that a lot of the libraries out there have documentation in Chinese and not in English.&lt;/p&gt;

&lt;p&gt;I don’t know about you, but my Mandarin is… How’d I put this? Non-existent. Seems like even if a library has excellent docs, you wouldn’t necessarily know it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Component libraries:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://quasar.dev/" rel="noopener noreferrer"&gt;&lt;strong&gt;Quasar&lt;/strong&gt;&lt;/a&gt;: It does not consider itself a library, but more of a framework. That, in my eyes is a bit confusing as it is based on Vue, but the idea is that you can use it to create websites and apps, meaning it uses a CLI to generate different outputs for web, mobile, desktop, SPA (Single Page Apps), SSR (Server Side Rendering), and more.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://vuetifyjs.com/en/" rel="noopener noreferrer"&gt;&lt;strong&gt;Vuetify&lt;/strong&gt;&lt;/a&gt;: Claims to be a no design skills required Open Source UI Library with beautifully handcrafted Vue Components. It has all the bells and whistles like most fully-fledged component libraries. Once more, you’d need to know the API to use this library, as well as get “locked in” to their component composition model.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://element-plus.org/en-US/" rel="noopener noreferrer"&gt;&lt;strong&gt;Element Plus&lt;/strong&gt;&lt;/a&gt;: As the website states, Element Plus is “a Vue 3-based component library for designers and developers”. Not sure how it differs from the rest of the pack, but it does have about the same variety of components to choose from. It has over 20K stars and over 150K downloads a week, which indicates its popularity.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.creative-tim.com/vuematerial/" rel="noopener noreferrer"&gt;&lt;strong&gt;VueMaterial&lt;/strong&gt;&lt;/a&gt;: As the name suggests, VueMaterial is a Vue implementation of Material design. The documentation boasts about being simple, lightweight, responsive, with an easy-to-use API. Sounds like all the right things for a component library.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F1d406aa2a6f5456c9badfae52ae927ec%3Fwidth%3D705" alt="A screenshot of a post by Evan You about Vue component libraries from X." width="705" height="519"&gt;
### &lt;strong&gt;Angular&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last time I used Angular in production was about 7 years ago, which is now called Angular.js. However, the framework is starting to have somewhat of a renaissance with &lt;a href="https://angular.io/guide/signals" rel="noopener noreferrer"&gt;signals being introduced&lt;/a&gt; and still a whole lot of enterprise companies using it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Component libraries:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://material.angular.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;Angular Material&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; Like all the rest of the material implementations for the various frameworks. All say about the same about themselves — being high quality, versatile, and frictionless. Whatever superlatives work, I guess 🤷🏽. Watch out for theming and trying to do anything that it doesn’t offer.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://primeng.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;PrimeNG&lt;/strong&gt;&lt;/a&gt;: Something nice about this collection is how you choose the base theme. You are presented with choosing design options that are taken from other popular design frameworks such as Material Design, Bootstrap, Soho, Fluent, Nano, and more. This is done with a visual editor, which is part of the theming options. PrimeNG also has a Figma UI kit, ready-made templates, and a SASS API.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ng-bootstrap.github.io/#/home" rel="noopener noreferrer"&gt;&lt;strong&gt;NG Bootstrap&lt;/strong&gt;&lt;/a&gt;: Yup, just as it sounds, a binding for Angular with Twitter Bootstrap (4.0). The caveat is that you need to learn both the API surface of the lib as well as knowing bootstrap class names.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Svelte﻿&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One thing that I really like about Svelte, is the fact that it has a lot of built-ins for handling things like styles and animations. For styling, you simply have a &lt;code&gt;style&lt;/code&gt; tag in your component file where your CSS lives and it is scoped only to that component. On top of that, having motion models that can easily handle &lt;code&gt;tween&lt;/code&gt; and &lt;code&gt;spring&lt;/code&gt; animations is quite great DX.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Headless:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://svelte-headlessui.goss.io/docs/2.0" rel="noopener noreferrer"&gt;&lt;strong&gt;Svelte Headless UI&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; A complete port of React Headless UI, which is compatible with &lt;a href="https://kit.svelte.dev/" rel="noopener noreferrer"&gt;SvelteKit&lt;/a&gt; (Svelte meta framework). See above for more details.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Component libraries:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.svelteui.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;SvelteUI&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; Yet another TypeScript, fully featured component library. It has over 50 components that are highly customizable. Ranging from layout components, actions, inputs, typography, and all that jazz that you need in a component library.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://smeltejs.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Smelte&lt;/strong&gt;&lt;/a&gt;: a UI framework built on top of Svelte and Tailwind CSS using Material Design spec. Plus, it’s a really fun name to say. The gist of it is that the lib has a Rollup plugin that you can define your themes, colors, etc. Then you need to import the libraries CSS and you’re good to go! This library has a Date Picker, navigation drawer and Treeviews, which are rare in most libs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;SolidJS&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.solidjs.com/" rel="noopener noreferrer"&gt;SolidJS&lt;/a&gt; has been around for a minute and a half, a lot less than most of the above frameworks. I am a fan of Ryan Carniato's work, however I haven't  had a chance to work with SolidJS extensively. &lt;/p&gt;

&lt;p&gt;It is most definitely a solid (pun intended) contender of choice for your next project. &lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="https://twitter.com/davedbase/status/1699895600916181488" rel="noopener noreferrer"&gt;Dave Di Biase&lt;/a&gt; for recommending these additions 🙏🏽.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Headless:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://kobalte.dev/docs/core/overview/introduction" rel="noopener noreferrer"&gt;Kobalte&lt;/a&gt;: An unstyled, accessible, and composable UI toolkit for building design system foundations. Inspired by AriaKit, RadixUI, React Araia, and Zag. From rummaging around in their docs, looks a lot like Radix implementation. Note: Still in beta. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Component Libraries:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://suid.io/" rel="noopener noreferrer"&gt;SUID&lt;/a&gt;: A port of MUI for SolidJS. As the docs state "same API. Same design", if you're coming from React and have used MUI, this will make you feel at home. Same caveats apply. One cool tool they have is a transformer from React 👉🏽 SolidJS.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://solid-libs.github.io/solid-bootstrap/" rel="noopener noreferrer"&gt;Solid Bootstrap&lt;/a&gt;: Once again, as the name suggests, a SolidJS wrapper on top of ye old Bootstrap. The difference being that instead of working with classes for the most parts, you'd need to use props (e.g. &lt;code&gt;variant&lt;/code&gt;). There's also a &lt;a href="https://solid-libs.github.io/solid-bootstrap/core/overview" rel="noopener noreferrer"&gt;"Core"&lt;/a&gt; offering which has a headless implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Qwik&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Being the newest framework on the list, the Qwik ecosystem is still new. As such, the options here are slim. However, one thing you could do is &lt;a href="https://www.builder.io/blog/resumable-react-how-to-use-react-inside-qwik" rel="noopener noreferrer"&gt;leverage the React ecosystem inside your Qwik app&lt;/a&gt; and use component libraries from there.&lt;/p&gt;

&lt;p&gt;There are also other community implementations in the works for &lt;a href="https://github.com/mizchi/qwik-vue" rel="noopener noreferrer"&gt;Vue&lt;/a&gt;, &lt;a href="https://github.com/QwikDev/qwik-angular" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;, and &lt;a href="https://github.com/mizchi/qwik-svelte/tree/main" rel="noopener noreferrer"&gt;Svelte&lt;/a&gt; that would open up those ecosystems as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Headless:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://qwikui.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;QwikUI&lt;/strong&gt;&lt;/a&gt;: Though still in beta, QwikUI offers a headless kit for building fully compatible WAI-ARIA components. Available in beta now are combo boxes, tabs, and accordion.There are drafts for tooltips, selects, and popovers. The team is also working on their own take on ShadCN/UI’s approach codenamed “&lt;a href="https://github.com/qwikifiers/qwik-ui/pull/398" rel="noopener noreferrer"&gt;Fluffy&lt;/a&gt;”.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Web components&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;As I’ve mentioned above, web components were meant to be the savior of the frontend world, but have failed to deliver. However, some companies have found success with them when it comes to UI web components. One of these companies is &lt;a href="https://www.salesforce.com/eu/?ir=1" rel="noopener noreferrer"&gt;SalesForce&lt;/a&gt; with their &lt;a href="https://developer.salesforce.com/docs/component-library/documentation/en/lwc" rel="noopener noreferrer"&gt;Lightning Web Components&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Other than that, I’ve only heard of one component library which I think is worth mentioning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://shoelace.style/" rel="noopener noreferrer"&gt;&lt;strong&gt;Shoelace&lt;/strong&gt;&lt;/a&gt;: Being built with web components means this library is framework agnostic, however, React is the only framework that was entitled to get first-class support. It also has built-in localization, and the components were built with &lt;a href="https://lit.dev/" rel="noopener noreferrer"&gt;Lit&lt;/a&gt;. Keep in mind that if you want the get your component content in SSR, this might not fit your needs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cross framework
&lt;/h3&gt;

&lt;p&gt;New agnostic libraries that aren’t necessarily built with Web components, but rather with CSS tooling have been popping up lately as well. Here are two interesting newcomers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://ark-ui.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;ArkUI&lt;/strong&gt;&lt;/a&gt;: Headless accessible components powered by state machines for React, Vue, and SolidJS. Also made by the creators of Zag.js and Chakra UI, this seems to be the middle ground in between those two offerings.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://flowbite.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Flowbite&lt;/strong&gt;&lt;/a&gt;: Components on top of Tailwind for not only JavaScript frameworks like React, Qwik, Vue, Svelte, Angular, and SolidJS, but also for popular meta frameworks such as Astro, Next.js, Remix, Nuxt, Meteor, and non JS frameworks such as Laravel, Symfony, Ruby on Rails, Pheonix, Django, and Flask.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ﻿ &lt;strong&gt;Design with fewer limitations, using&lt;/strong&gt; &lt;a href="http://builder.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;Builder.io&lt;/strong&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;While on the subject of framework-agnostic solutions, did you know that with &lt;a href="https://www.builder.io/m/headless-cms-visual-guide" rel="noopener noreferrer"&gt;Builder’s Headless Visual CMS&lt;/a&gt; you can let your designers use your own components inside a drag-and-drop UI?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F287175b2d6d640d4babfb44bbc0d2966%3Fwidth%3D705" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F287175b2d6d640d4babfb44bbc0d2966%3Fwidth%3D705" alt="Untitled" width="705" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whatever stack you’re using, with whichever component library, you can register component code that developers have written and use them to compose pages in a visual way.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As can be inferred from this lengthy post, there is an abundance of options to choose from.&lt;/p&gt;

&lt;p&gt;Choosing the right solution for you and/or your team can be either a hell of a productivity booster or a huge foot gun.&lt;/p&gt;

&lt;p&gt;I myself have experienced the effect of a bad choices that were made. In my case, it was Material UI that made it almost impossible to get the functionality that our product team desired. We had to either completely rewrite components and even use a forked version of MUI, just to get to what we wanted.&lt;/p&gt;

&lt;p&gt;Be wary of your choices.&lt;/p&gt;

&lt;p&gt;Hopefully, this post has given you a good enough overview of what’s out there now, and got you seriously thinking wether you need a library or wether it’s a good enough investment to roll out your own. Not only for the sake of your product team, but for the sake of your users.&lt;/p&gt;

&lt;p&gt;Just remember, your users don’t care what solution you use, like &lt;a href="https://www.builder.io/blog/the-tailwind-css-drama-your-users-don't-care-about" rel="noopener noreferrer"&gt;they don’t care if you’re using Tailwind&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Use what is right for what you’re building and the requirements of the project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" width="405" height="143"&gt;&lt;/a&gt;&lt;br&gt;
      &lt;br&gt;
    &lt;/p&gt;

&lt;p&gt;Visually build with your components&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;Builder.io&lt;/a&gt; is a visual editor that connects to any site or app and lets you &lt;a href="https://www.builder.io/m/products" rel="noopener noreferrer"&gt;drag and drop&lt;/a&gt; with &lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;your components&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://builder.io/signup" rel="noopener noreferrer"&gt;Try it out&lt;/a&gt; &lt;a href="https://dev.to/m/developers"&gt;Learn more&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Dynamically render your components&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;MyPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="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;BuilderComponent&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;registerComponents&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;MyHero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyProducts&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  &lt;em&gt;Read the &lt;a href="https://www.builder.io/blog/25-plus-ui-component-libraries" rel="noopener noreferrer"&gt;full post&lt;/a&gt; on the &lt;a href="https://www.builder.io/blog" rel="noopener noreferrer"&gt;Builder.io blog&lt;/a&gt;&lt;/em&gt;
&lt;/h5&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>ui</category>
    </item>
    <item>
      <title>Building Adaptive User Interfaces in React Native</title>
      <dc:creator>Yoav Ganbar</dc:creator>
      <pubDate>Mon, 04 Sep 2023 11:32:38 +0000</pubDate>
      <link>https://dev.to/builderio/building-adaptive-user-interfaces-in-react-native-np7</link>
      <guid>https://dev.to/builderio/building-adaptive-user-interfaces-in-react-native-np7</guid>
      <description>&lt;p&gt;&lt;em&gt;Written by &lt;a href="https://twitter.com/CodevolutionWeb" rel="noopener noreferrer"&gt;Vishwas Gopinath&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The world of mobile development is constantly shifting, and with it comes the need for user interfaces that can adapt to any device or orientation. React Native offers a rich set of tools and techniques to build such interfaces.&lt;/p&gt;

&lt;p&gt;In this article, we will explore how to design responsive and adaptive UIs in React Native, with a focus on varying device sizes, orientations, safe areas, and platform-specific code.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Adaptive user interfaces&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;React Native provides components and APIs to adapt to changes in device sizes and orientations. Since users may have different devices ranging from compact phones to larger tablets, it's essential to ensure that the app's UI adapts to these variations.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Dimensions API&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The Dimensions API in React Native allows you to obtain the device's width and height. You can use these values to adapt styles based on the device size. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Dimensions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;windowWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Dimensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;window&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;width&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;windowHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Dimensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;window&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;height&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;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;windowWidth&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;70%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;90%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;windowHeight&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;60%&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;90%&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="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;windowWidth&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F52401459d4c04bb9809dd0f0846e6c56%3Fwidth%3D705" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F52401459d4c04bb9809dd0f0846e6c56%3Fwidth%3D705" width="705" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, the Dimensions API has a drawback: it doesn't dynamically update when the window dimensions change, such as during orientation changes or with foldable phones.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;useWindowDimensions hook&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To overcome the limitations of the Dimensions API, React Native introduced the &lt;code&gt;useWindowDimensions&lt;/code&gt; hook. This hook simplifies the process of adapting styles that respond to changes in device dimensions. Here's how you can use it:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useWindowDimensions&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;windowWidth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useWindowDimensions&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;width&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;windowHeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useWindowDimensions&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Ffd422826d44a44cbb29f4805d8145b62%3Fwidth%3D705" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Ffd422826d44a44cbb29f4805d8145b62%3Fwidth%3D705" width="705" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s worth noting that &lt;code&gt;useWindowDimensions&lt;/code&gt; is the recommended approach to work with device dimensions in React Native.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;SafeAreaView&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;SafeAreaView&lt;/code&gt; component in React Native ensures that content is rendered within the safe area boundaries of a device. By using SafeAreaView, you can adapt your UI to avoid physical limitations like notches or rounded corners, providing a seamless user experience across different device designs. Here's an example of how to use &lt;code&gt;SafeAreaView&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;SafeAreaView&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;SafeAreaView&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* Your content here */&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;/SafeAreaView&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fa03cb4eb8381442486a00bccb77e19a9%3Fwidth%3D705" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fa03cb4eb8381442486a00bccb77e19a9%3Fwidth%3D705" width="705" height="397"&gt;&lt;/a&gt; &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F86cb85533e5d469e8ffeed519e2a794a%3Fwidth%3D45" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F86cb85533e5d469e8ffeed519e2a794a%3Fwidth%3D45" width="45" height="46"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SafeAreaView&lt;/code&gt; is a component specific to iOS.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Platform-specific code&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When developing a cross-platform app, you may need to tailor your code to specific platforms. React Native offers two approaches for this, allowing you to adapt your UI to cater to the unique design guidelines and user expectations of different platforms.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Platform module&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The Platform module detects the platform on which the app is running, so you can implement platform-specific code. You can use &lt;code&gt;Platform.OS&lt;/code&gt; for small changes or &lt;code&gt;Platform.select&lt;/code&gt; for more comprehensive platform-specific styles. Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;StyleSheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;marginTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Platform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;OS&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;android&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;Platform&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;ios&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;purple&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;android&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bold&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&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;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F452ba7685bcb4d5dae0b0dfc8e617776%3Fwidth%3D705" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F452ba7685bcb4d5dae0b0dfc8e617776%3Fwidth%3D705" width="705" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Platform-specific file extensions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;For more complex platform-specific scenarios, you can split your code into separate files with &lt;code&gt;.ios&lt;/code&gt; and &lt;code&gt;.android&lt;/code&gt; extensions. React Native detects the extension and loads the relevant platform file when required. Here's an example of how you can create a platform-specific button component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// CustomButton.ios.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Pressable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CustomButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Pressable&lt;/span&gt;
    &lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
      &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lightblue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;purple&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&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;title&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;/Text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Pressable&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;CustomButton&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// CustomButton.android.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Pressable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react-native&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CustomButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Pressable&lt;/span&gt;
    &lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;
      &lt;span class="na"&gt;justifyContent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;alignItems&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;center&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lightblue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Text&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;18&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;title&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;/Text&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Pressable&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;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F485efc7bff694e849cda013f67f57f91%3Fwidth%3D705" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F485efc7bff694e849cda013f67f57f91%3Fwidth%3D705" width="705" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Additional considerations&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Besides the mentioned components and APIs, you might also consider using the &lt;code&gt;LayoutAnimation&lt;/code&gt; library for smooth transitions and animations when adapting to different screen sizes and orientations.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Building adaptive user interfaces in React Native requires a deep understanding of the tools and techniques available. By leveraging the Dimensions API, &lt;code&gt;useWindowDimensions&lt;/code&gt; hook, &lt;code&gt;SafeAreaView&lt;/code&gt; component, and platform-specific coding strategies, you can create responsive and adaptive UIs that provide an optimal user experience across different devices and platforms.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" width="405" height="143"&gt;&lt;/a&gt;&lt;br&gt;
      &lt;br&gt;
    &lt;/p&gt;

&lt;p&gt;Visually build with your components&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;Builder.io&lt;/a&gt; is a headless CMS that lets you &lt;a href="https://www.builder.io/m/products" rel="noopener noreferrer"&gt;drag and drop&lt;/a&gt; with &lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;&lt;strong&gt;your&lt;/strong&gt; components&lt;/a&gt; right within your existing site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://builder.io/signup" rel="noopener noreferrer"&gt;Try it out&lt;/a&gt; &lt;a href="https://dev.to/m/developers"&gt;Learn more&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Dynamically render your components&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;MyPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="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;BuilderComponent&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;registerComponents&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;MyHero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyProducts&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  &lt;em&gt;Read the &lt;a href="https://www.builder.io/blog/adaptive-ui-react-native" rel="noopener noreferrer"&gt;full post&lt;/a&gt; on the &lt;a href="https://www.builder.io/blog" rel="noopener noreferrer"&gt;Builder.io blog&lt;/a&gt;&lt;/em&gt;
&lt;/h5&gt;

</description>
      <category>webdev</category>
      <category>reactnative</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>Moving from Wordpress to Builder.io</title>
      <dc:creator>Yoav Ganbar</dc:creator>
      <pubDate>Sat, 02 Sep 2023 07:44:12 +0000</pubDate>
      <link>https://dev.to/builderio/moving-from-wordpress-to-builderio-24o7</link>
      <guid>https://dev.to/builderio/moving-from-wordpress-to-builderio-24o7</guid>
      <description>&lt;p&gt;&lt;em&gt;Written by &lt;a href="https://www.linkedin.com/in/gustavo-garcia-it/" rel="noopener noreferrer"&gt;Gustavo Garcia&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Moving content from your existing CMS can be much easier than you think. Already use a CMS like Wordpress? Do you have tools to export your content to a defined structure like JSON or other? If so, you have a pretty easy path to move your content to Builder.&lt;/p&gt;

&lt;h2&gt;
  
  
  ﻿Export your content
&lt;/h2&gt;

&lt;p&gt;This section shows you how to migrate your content to Builder.io.&lt;/p&gt;

&lt;p&gt;Export your content on a defined structure you can work with, as an example JSON format. Make sure you have your content well-defined in block structures like this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"padding-top: 8px"&lt;/span&gt; &lt;span class="na"&gt;classname=&lt;/span&gt;&lt;span class="s"&gt;"title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example would be parsed 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="p"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tag&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;classname&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;style&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;padding-top&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;children&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;Create some &lt;a href="https://www.builder.io/c/docs/custom-components-intro" rel="noopener noreferrer"&gt;custom components&lt;/a&gt; in code that translates to your components from your CMS. For example, let's say we have a Hero Component that exists in your current CMS and is exported:&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="p"&gt;{&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;layout_type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;HERO&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
   &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;props&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;This is my hero title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;subtitle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
         &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My hero subtitle with a cool slogan&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tag&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;h2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;media&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
         &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ID&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;11029&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;11029&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What is the universe?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;filename&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sample-file.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://cool-wordpress/wp-includes/images/media/default.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;alt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What is the universe?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What is the universe?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;caption&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What is the universe?&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hero-v1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mime_type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/svg+xml&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;subtype&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;svg+xml&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;icon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://cool-wordpress/wp-includes/images/media/default.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;width&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;704&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;height&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;528&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sizes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
               &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;thumbnail&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://cool-wordpress/wp-includes/images/media/default-v3.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;thumbnail-width&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;150&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;thumbnail-height&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;150&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://cool-wordpress/wp-includes/images/media/default-v3.svg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;medium-width&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;300&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
               &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;medium-height&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;300&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;background&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;custom&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;backgroundColor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#123833&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;colorModifier&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;size&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;s&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hasButton&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="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="p"&gt;:{&lt;/span&gt;
         &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;label&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Click here&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
         &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;action&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;link&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/call-to-action&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;This would turn into a custom component in your code such as:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;MyCustomButton&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;./components/MyCustomButton&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;// defined props like title, subTitle, hasButton, buttonLink&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;Hero&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;subTitle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hasButton&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;buttonLink&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="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&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;title&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Default hero title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h3&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;subTitle&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Default hero subtitle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h3&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;hasButton&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyCustomButton&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;buttonLink&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Register your created custom components in Builder.io so you can use them within the Visual Editor:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Builder&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;@builder.io/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Hero&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;./Hero&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Hero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hero&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;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;title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;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;subtitle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;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;hasButton&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;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;buttonLink&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&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;h2&gt;
  
  
  Create your migration script
&lt;/h2&gt;

&lt;p&gt;Now that you have your content exported and your custom components ready, it's time to get that content into Builder.io so you can edit and publish. Below we have written some step-by-step instructions on how to create your migration script.&lt;/p&gt;

&lt;p&gt;Your migration script should:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read your content from your exported files (in this example JSON files) looking for blocks and content of interest, which will be now parsed to your custom components:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./content.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MODEL_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog-page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;starting script...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blocks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&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;contentJson&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;layoutItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;let&lt;/span&gt; &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;layout_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;title&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;subtitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;subtitle&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&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;layoutItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;layout_type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hero&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;hasButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;hasButton&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;button&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;button&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;layoutItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;layout_type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Text&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 you have a custom component for text blocks&lt;/span&gt;
      &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="c1"&gt;// ... continue to identify your blocks of interest&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// push your components to your blocks array to be rendered on the model layout&lt;/span&gt;
    &lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@builder.io/sdk:Element&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@version&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;component&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="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;layoutType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;options&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;As in the above example, when you find a block of interest, identify the custom component that best suits that block and add the custom component with its options to the blocks array to be rendered on your model layout — in this case &lt;code&gt;blog-page&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, write your content to Builder.io using the &lt;a href="https://www.builder.io/c/docs/write-api" rel="noopener noreferrer"&gt;Write API&lt;/a&gt; so you can edit and publish from the editor:&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="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;postData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;res&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;axios&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://builder.io/api/v1/write/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;MODEL_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&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;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your private space key goes here&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&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="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// each time you iterate over a page,&lt;/span&gt;
&lt;span class="c1"&gt;// you can call the write API to create a new entry&lt;/span&gt;
&lt;span class="c1"&gt;// with the blocks identified&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&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;postData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;property&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;urlPath&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;operator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;is&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// can be `startsWith` to match any urls that starts with value&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="c1"&gt;// must start with /&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;metaTags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metaTags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;blocks&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;So the final migration script on this example should be like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./content.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;postData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;res&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;axios&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;post&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`https://builder.io/api/v1/write/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;MODEL_NAME&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&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;Authorization&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Your private space key goes here&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&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="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&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;MODEL_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blog-page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;starting...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blocks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&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;contentJson&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;layoutItem&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;let&lt;/span&gt; &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;layout_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;title&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;subtitle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;subtitle&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&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;layoutItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;layout_type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hero&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;hasButton&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;hasButton&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;button&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;button&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;layoutItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;layout_type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Text&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 you have a custom component for text blocks&lt;/span&gt;
      &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&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;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="c1"&gt;// ... continue to identify your blocks of interest&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// push your components to your blocks array to be rendered on the model layout&lt;/span&gt;
    &lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@builder.io/sdk:Element&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@version&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;component&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="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;layoutItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;layoutType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;


  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&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;postData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replaceAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;property&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;urlPath&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;operator&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;is&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// can be `startsWith` to match any urls that starts with value&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="c1"&gt;// must start with /&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;metaTags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contentJson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metaTags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;blocks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;new entry added&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="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;log&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="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Additional considerations
&lt;/h2&gt;

&lt;p&gt;This article showed how to migrate blog pages exported from Wordpress as JSON format files. Even so, you could use this same process to migrate any content to Builder.io exported from the most famous and used of CMSs on the market.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Migrating content from your existing CMS to Builder.io can be straightforward and fast — just make sure to export your content in a way that you can read it while keeping your components as well-defined as possible. This will help a lot in the migration process. Using these techniques, you can smoothly migrate hundreds or even thousands of pages as many of our customers do!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" width="405" height="143"&gt;&lt;/a&gt;&lt;br&gt;
      &lt;br&gt;
    &lt;/p&gt;

&lt;p&gt;Visually build with your components&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;Builder.io&lt;/a&gt; is a headless CMS that lets you &lt;a href="https://www.builder.io/m/products" rel="noopener noreferrer"&gt;drag and drop&lt;/a&gt; with &lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;&lt;strong&gt;your&lt;/strong&gt; components&lt;/a&gt; right within your existing site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://builder.io/signup" rel="noopener noreferrer"&gt;Try it out&lt;/a&gt; &lt;a href="https://dev.to/m/developers"&gt;Learn more&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Dynamically render your components&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;MyPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="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;BuilderComponent&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;registerComponents&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;MyHero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyProducts&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  &lt;em&gt;Read the &lt;a href="https://www.builder.io/blog/moving-from-wordpress-to-builder" rel="noopener noreferrer"&gt;full post&lt;/a&gt; on the &lt;a href="https://www.builder.io/blog" rel="noopener noreferrer"&gt;Builder.io blog&lt;/a&gt;&lt;/em&gt;
&lt;/h5&gt;

</description>
      <category>webdev</category>
      <category>cms</category>
      <category>wordpress</category>
      <category>frontend</category>
    </item>
    <item>
      <title>What is a Headless CMS: a Visual Guide</title>
      <dc:creator>Yoav Ganbar</dc:creator>
      <pubDate>Thu, 31 Aug 2023 17:58:28 +0000</pubDate>
      <link>https://dev.to/builderio/what-is-a-headless-cms-a-visual-guide-3b5i</link>
      <guid>https://dev.to/builderio/what-is-a-headless-cms-a-visual-guide-3b5i</guid>
      <description>&lt;p&gt;Last updated: August 30, 2023&lt;/p&gt;

&lt;p&gt;In today’s fast-paced digital age, content management systems (CMS) have become essential tools for efficiently managing and delivering content across various platforms. Among the various CMS options available, the concept of a &lt;em&gt;headless CMS&lt;/em&gt; has emerged as a powerful and flexible solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Headless CMS in 30 seconds&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/JOWJt3pC_lg"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

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

&lt;p&gt;A content management system (CMS) is a software platform that enables users to create, edit, organize, and publish digital content, such as articles, images, videos, and more.&lt;/p&gt;

&lt;p&gt;CMSs have long been the backbone of digital content creation and delivery. Traditional CMS platforms, including open-source solutions like &lt;a href="https://wordpress.com/" rel="noopener noreferrer"&gt;WordPress&lt;/a&gt;, &lt;a href="https://www.joomla.org/" rel="noopener noreferrer"&gt;Joomla&lt;/a&gt;, and &lt;a href="https://www.drupal.org/" rel="noopener noreferrer"&gt;Drupal&lt;/a&gt;, have been popular due to their ease of use and integration of content creation and presentation.&lt;/p&gt;

&lt;p&gt;Here's a visual representation of a traditional CMS:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fe2caa2bb6c664c31be2dcf2b332f34af%3Fwidth%3D820" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fe2caa2bb6c664c31be2dcf2b332f34af%3Fwidth%3D820" alt="Diagram of a traditional CMS" width="820" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A traditional CMS operates as a monolithic application. All of the different functions, such as content creation, storage, and delivery, are tightly integrated into a single system. Users use a WYSIWYG editor within the admin interface to create and oversee content, which is subsequently transformed into a responsive user interface that adapts to various devices.&lt;/p&gt;

&lt;p&gt;However, the tight coupling of content creation and presentation in traditional CMS brings about several challenges. One of the main issues is the lack of flexibility when it comes to delivering content across websites, mobile apps, IoT devices, smartwatches, and any emerging technologies.&lt;/p&gt;

&lt;p&gt;Each platform often requires specific content formatting and delivery mechanisms, which means content must be managed separately for each touchpoint. This not only creates inefficiencies but also leads to maintenance problems and inconsistencies in user experiences. The need for a more flexible approach gave rise to the concept of CMS with a headless architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is a headless CMS?&lt;/strong&gt;&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;At its core, a headless content management system decouples the content creation and presentation layers. Unlike traditional CMS platforms, a headless CMS does not enforce a specific front-end presentation (the "head") for displaying content.&lt;/p&gt;

&lt;p&gt;Instead, it provides APIs (Application Programming Interfaces) that help developers fetch from a single content source and deliver data to any desired front-end, such as websites, mobile apps, IoT devices, and more. Moreover, the headless CMS often provides both RESTful API and GraphQL API options, ensuring versatile and efficient content fetching capabilities.&lt;/p&gt;

&lt;p&gt;Here's a visual representation of a headless CMS:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fa0ab3fd54e86489abc3dd264b7cbac81%3Fwidth%3D820" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fa0ab3fd54e86489abc3dd264b7cbac81%3Fwidth%3D820" alt="Diagram of a headless CMS" width="820" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In contrast to traditional monolithic setups, a headless CMS adopts a &lt;em&gt;composable app&lt;/em&gt; approach. In this approach, various functionalities such as content creation, external integration, and delivery function independently yet cohesively.&lt;/p&gt;

&lt;p&gt;Users engage with a simple data editor to efficiently create and manage content. This content then undergoes a seamless transition into content APIs, which can be used by a technology of choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Headless CMS: an analogy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of a traditional CMS as comparable to purchasing a frozen pizza — it's convenient but confines you to ready-made choices. In contrast, a headless CMS is like having a fully stocked kitchen complete with fresh ingredients at your disposal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F3fa4460d1d444f55a8ed39ec7317b940%3Fwidth%3D820" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F3fa4460d1d444f55a8ed39ec7317b940%3Fwidth%3D820" alt="Visual of the pizza analogy for a CMS" width="820" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine crafting not just a pizza, but also experimenting with gourmet pasta dishes or crafting delectable calzones using different techniques and flavors from the same box of ingredients. Such is the potential of a headless CMS.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How a headless CMS works&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A headless CMS functions through a straightforward yet powerful process.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Content creation and management&lt;/strong&gt;: Content creators and administrators use the headless CMS interface to create, edit, and organize content, including text, images, videos, metadata, and other media assets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API-based architecture&lt;/strong&gt;: The headless CMS stores content in a database and exposes it through APIs, so developers can programmatically retrieve structured content, such as JSON or XML.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Front-end development and consumption&lt;/strong&gt;: Developers build front-end applications that interact with headless CMS APIs so that the front-end can retrieve and display content based on design and user experience requirements.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F11321454487e4317b8966f660a0e9246%3Fwidth%3D820" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F11321454487e4317b8966f660a0e9246%3Fwidth%3D820" alt="Visual of connecting one content API to multiple apps" width="820" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Benefits of a headless CMS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Using a headless CMS comes with a plethora of advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Future-Proofing:&lt;/strong&gt; The decoupled CMS nature provides easy adaptation to emerging technologies and changes in the digital landscape.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility:&lt;/strong&gt; Developers can implement unique user experiences using any tech stack; next.js, gatsby, vue.js, or react, to name a few. This allows for more creativity and customization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Performance:&lt;/strong&gt; Thanks to optimized front-end design, API-driven content delivery, and integration with CDNs (Content Delivery Networks), sites and apps using a headless CMS improve loading times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; Independent scaling of front-end and back-end ensures better performance and handling of traffic spikes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration:&lt;/strong&gt; Content creators and developers can work independently, promoting seamless collaboration and faster iteration cycles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Reusability:&lt;/strong&gt; A single content repository enables repurposing content across multiple platforms and devices, such as websites, mobile apps, smart devices, and more.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Ffa447860ac824b53806fefa0787adc23%3Fwidth%3D820" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Ffa447860ac824b53806fefa0787adc23%3Fwidth%3D820" alt="Visualization of the 6 benefits of a headless CMS" width="820" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Who's using headless CMSs&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Headless CMS is embraced by diverse industries and organizations that value agility, customization, and seamless cross-platform content delivery.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Developers and agencies&lt;/strong&gt;: Web developers and digital agencies often use headless CMS because it allows them to build custom front-end digital experiences for their clients. They have the freedom to choose the best technologies for the job and create highly tailored and unique websites or applications. They can also optimize better for SEO.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;E-commerce businesses&lt;/strong&gt;: E-commerce platforms often use headless CMS to manage product information, marketing content, and other relevant data. With a headless CMS, they can easily deliver content to multiple channels, such as websites, mobile apps, voice assistants, and other devices to deliver excellent customer experiences for the end user.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Media and publishing companies&lt;/strong&gt;: Companies that handle a large volume of content, such as news outlets, blogs, and magazines, use headless CMS to streamline their content management processes. The decoupled architecture allows them to distribute and reuse content across various platforms efficiently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Marketing teams&lt;/strong&gt;: Marketing teams can use headless CMS to manage marketing content, landing pages, and promotional material across different platforms without relying on IT teams for implementation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile app developers&lt;/strong&gt;: Headless CMS helps mobile app developers to manage app content without needing frequent updates through app stores. The same content can be delivered to users in real-time without requiring app updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Many others:&lt;/strong&gt; Headless CMSs are popular in many industries such as education, government agencies, startups, and virtually anyone with sites and apps to maintain.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Traditional CMS versus headless CMS in a snapshot&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fe8980b5f80754b209e19057588be2cbb%3Fwidth%3D820" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fe8980b5f80754b209e19057588be2cbb%3Fwidth%3D820" alt="Traditional vs headless CMS diagrams annotated" width="820" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Traditional CMS&lt;/th&gt;
&lt;th&gt;Headless CMS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Content Presentation&lt;/td&gt;
&lt;td&gt;Frontend is tightly linked to backend&lt;/td&gt;
&lt;td&gt;Content is separated from presentation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Technology Stack&lt;/td&gt;
&lt;td&gt;Uses a single technology stack&lt;/td&gt;
&lt;td&gt;Provides APIs for content delivery to any technology stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Development Freedom&lt;/td&gt;
&lt;td&gt;Developers work within the CMS's framework&lt;/td&gt;
&lt;td&gt;Developers choose their technology stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Monolithic nature may lead to performance issues&lt;/td&gt;
&lt;td&gt;Separation enhances performance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scalability&lt;/td&gt;
&lt;td&gt;Scaling may be constrained by the CMS&lt;/td&gt;
&lt;td&gt;Can handle increased traffic and content&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content Updates&lt;/td&gt;
&lt;td&gt;Backend &amp;amp; Frontend updates often interdependent&lt;/td&gt;
&lt;td&gt;Content is separated from presentation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to Market&lt;/td&gt;
&lt;td&gt;Template-based approach can be time-consuming&lt;/td&gt;
&lt;td&gt;Faster as developers work in parallel on frontend and backend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Omnichannel&lt;/td&gt;
&lt;td&gt;Requires extra effort to deliver content across channels&lt;/td&gt;
&lt;td&gt;Content can be easily distributed to multiple channels&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use Cases&lt;/td&gt;
&lt;td&gt;Well-suited for simpler websites or blogs&lt;/td&gt;
&lt;td&gt;Suitable for complex, dynamic, and omnichannel projects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maintenance &amp;amp; Upgrades&lt;/td&gt;
&lt;td&gt;More centralized but may be harder to upgrade&lt;/td&gt;
&lt;td&gt;Easier to maintain and update due to separation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Drawbacks of a headless CMS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One major challenge of a typical headless CMS is the lack of a visual interface for finding and editing content. This can create difficulties in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Locating the required content to edit&lt;/li&gt;
&lt;li&gt;Intuitively previewing and editing your content&lt;/li&gt;
&lt;li&gt;Making non-trivial changes without needing engineering assistance and deployment&lt;/li&gt;
&lt;li&gt;Testing and personalizing content&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Read more on the &lt;a href="https://www.builder.io/blog/the-problem-with-a-headless-cms" rel="noopener noreferrer"&gt;problems with a headless CMS&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Fixing the drawbacks with a Visual Headless CMS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To overcome these challenges and improve user experience, a new type of headless CMS has emerged. Known as a &lt;a href="https://www.builder.io/blog/visual-headless-cms" rel="noopener noreferrer"&gt;&lt;em&gt;Visual Headless CMS&lt;/em&gt;&lt;/a&gt;, it provides a visual, component-driven approach for creating content experiences.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F2ad42cdad7264ef6845d2aa74237e08d%3Fwidth%3D820" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F2ad42cdad7264ef6845d2aa74237e08d%3Fwidth%3D820" alt="Diagram of a Visual Headless CMS" width="820" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Key features of Visual Headless CMS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A Visual Headless CMS includes all the features of a regular headless CMS, and also includes features that take the user experience to the next level.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Drag-and-drop Visual Editor&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A Visual Headless CMS gives users a way to effortlessly drag and drop content elements, such as images, text blocks, videos, custom components, and more to create captivating and dynamic web pages.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/f6NQSt03VG4"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Integrated Approach&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Developers and designers find their perfect playground, as Visual Headless CMS offers the flexibility to blend visual building with coding for ultimate customization.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;One-Click Experimentation&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A Visual Headless CMS streamlines the publishing process, enabling swift delivery of new pages, A/B tests, personalization, localization, roles, and permissions.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/isjoh54sDJk"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Full control over content workflow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With visual tools, content creators can preview their changes in real-time, simplifying collaboration and streamlining the review process.&lt;/p&gt;

&lt;p&gt;Here’s a snapshot of the capabilities of a headless CMS versus a Visual Headless CMS&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Headless CMS&lt;/th&gt;
&lt;th&gt;Visual Headless CMS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Visual Editing&lt;/td&gt;
&lt;td&gt;Offers a basic, form-based content creation interface&lt;/td&gt;
&lt;td&gt;Provides a feature-rich, drag-and-drop content editor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Live Preview&lt;/td&gt;
&lt;td&gt;Lacks the ability to preview content in real-time, with some (limited) exceptions&lt;/td&gt;
&lt;td&gt;Gives an instant preview of edits and changes on a live page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Collaboration&lt;/td&gt;
&lt;td&gt;Limited collaboration, requiring business teams to depend on developers for significant features&lt;/td&gt;
&lt;td&gt;Facilitates effective real time collaboration among developers, marketing teams, and designers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A/B Testing&lt;/td&gt;
&lt;td&gt;Requires developer involvement to create and deploy tests&lt;/td&gt;
&lt;td&gt;Enables easy A/B testing with analytics, without developer intervention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Personalization&lt;/td&gt;
&lt;td&gt;Requires developer involvement to create and deploy personalized variations&lt;/td&gt;
&lt;td&gt;Empowers personalization by leveraging customer data and targeting specific user groups with tailored content&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Visual Headless CMS impact on code&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With a Visual Headless CMS, the overall structure is the same as any other headless CMS — content is fetched as JSON and rendered within your stack.&lt;/p&gt;

&lt;p&gt;The key difference with a Visual Headless CMS, is you get first-class integrations for your choice of framework that let you reduce code clutter and embrace a more component-driven flow as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F18163f977b43451c9c4ec8ab875f6f6b%3Fwidth%3D820" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F18163f977b43451c9c4ec8ab875f6f6b%3Fwidth%3D820" alt="Comparison of simpler code with a visual headless CMS vvs a typical headless CMS" width="820" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ultimately, this helps developers avoid hard-coding layouts and component compositions — the CMS handles that while developers focus on components.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Builder.io Visual Headless CMS&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;At &lt;a href="https://www.builder.io" rel="noopener noreferrer"&gt;Builder.io&lt;/a&gt;, we offer a powerful combination of user-friendly visual tools, collaboration-friendly features, and efficient publishing capabilities. We have a &lt;a href="https://chrome.google.com/webstore/detail/builderio/cfldfgibklhmjhnkfighkbafbkbfcmij" rel="noopener noreferrer"&gt;Google Chrome extension&lt;/a&gt; to easily help you with content editing within the web browser, along with a &lt;a href="https://www.figma.com/community/plugin/747985167520967365/Builder.io---Design-to-React-Code-with-AI" rel="noopener noreferrer"&gt;Figma plugin&lt;/a&gt; to make a smoother transition from design to web page. You can incrementally adopt our Visual Headless CMS or rebuild your frontend from scratch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.builder.io/signup" rel="noopener noreferrer"&gt;Get started free&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cms</category>
      <category>webdev</category>
      <category>programming</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Unleash the Power of the Platform with These HTML Tags</title>
      <dc:creator>Yoav Ganbar</dc:creator>
      <pubDate>Tue, 15 Aug 2023 07:39:24 +0000</pubDate>
      <link>https://dev.to/builderio/unleash-the-power-of-the-platform-with-these-html-tags-2i5n</link>
      <guid>https://dev.to/builderio/unleash-the-power-of-the-platform-with-these-html-tags-2i5n</guid>
      <description>&lt;p&gt;Get ready to spice up your HTML game with some seriously underrated tags! In this blog post we'll uncover some hidden gems that will make your web development skills shine brighter than a disco ball. From the sassy &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; tag to the snazzy &lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt; tag, we'll cover a variety of elements that will take your web pages from drab to fab. So, buckle up and let's explore some exciting new ways to level up your HTML coding skills.&lt;/p&gt;

&lt;h2&gt;
  
  
  The OG HTML modal - &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;How many times did you reach for a library when you needed a modal?&lt;/p&gt;

&lt;p&gt;I know I have so many times…&lt;/p&gt;

&lt;p&gt;However, since last year, when Safari and Firefox added support for the &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; element, you can finally “use the platform”!&lt;/p&gt;

&lt;p&gt;Creating a basic dialog looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;Open&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dialog&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Hello World!&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;OK&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dialog&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whatever is in the &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; tag will be hidden from a user. The button in the above code is the means for the user to open the dialog, but in order for this to work we’d need to add a bit of JavaScript:&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;dialogElm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dialog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buttonElm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&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="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;buttonElm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;dialogElm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showModal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the video below, you can see how clicking on the &lt;code&gt;open&lt;/code&gt; button opens the modal, and the &lt;code&gt;OK&lt;/code&gt; button inside the dialog closes it:&lt;/p&gt;


      
    

&lt;p&gt;Let’s break it down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In order to show the dialog (modal) we use the built in &lt;code&gt;showModal()&lt;/code&gt; function on the &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; element. This adds the &lt;code&gt;aria-modal="true"&lt;/code&gt; attribute for accessibility purposes as well as provide the ability to close the modal with the &lt;code&gt;Esc&lt;/code&gt; key. Furthermore, the initial focus of the user will be set on the first nested focusable element.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;&amp;lt;form method="dialog"&amp;gt;&lt;/code&gt; with the &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; (which defaults to &lt;code&gt;type=submit&lt;/code&gt;) allows us to close to dialog. Another option is to provide the button with the &lt;code&gt;formmethod="dialog"&lt;/code&gt; attribute and remove the method from the &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Styling the backdrop
&lt;/h3&gt;

&lt;p&gt;You can customize the backdrop background using the &lt;code&gt;::backdrop&lt;/code&gt; pseudo element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;::backdrop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="err"&gt;//&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;can&lt;/span&gt; &lt;span class="err"&gt;go&lt;/span&gt; &lt;span class="err"&gt;all&lt;/span&gt; &lt;span class="err"&gt;out,&lt;/span&gt; &lt;span class="err"&gt;if&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;want&lt;/span&gt; &lt;span class="err"&gt;😉&lt;/span&gt;
 &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;lightcoral&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what our styles look like in action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Ff4e6e5850ca842dabd26eecf44ce041f%3Fwidth%3D800" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Ff4e6e5850ca842dabd26eecf44ce041f%3Fwidth%3D800" alt="A screenshot of an open dialog with a different backdrop color" width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Returning values from the dialog
&lt;/h3&gt;

&lt;p&gt;When using a &lt;code&gt;&amp;lt;form&amp;gt;&lt;/code&gt; element inside a &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; element, it’s possible to get a return value from the &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; &lt;code&gt;close&lt;/code&gt; event.&lt;/p&gt;

&lt;p&gt;Let’s observe a basic example. This is the HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"show"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Open&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;output&amp;gt;&amp;lt;/output&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dialog&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Hello Dialog!&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;form&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"name-input"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Enter something&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"name-input"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"ok"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;formmethod=&lt;/span&gt;&lt;span class="s"&gt;"dialog"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;OK&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dialog&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the Javascript:&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;dialogElm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dialog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;showButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;show&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;outputElm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;nameInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;name-input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;okButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ok&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// open the modal&lt;/span&gt;
&lt;span class="nx"&gt;showButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;dialogElm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showModal&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// set the input value as the button value&lt;/span&gt;
&lt;span class="nx"&gt;nameInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;change&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;okButton&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;=&lt;/span&gt; &lt;span class="nx"&gt;nameInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// when the dialog close event is sent, set the &amp;lt;output&amp;gt; as the return value&lt;/span&gt;
&lt;span class="nx"&gt;dialogElm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;outputElm&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;=&lt;/span&gt; &lt;span class="nx"&gt;dialogElm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;returnValue&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No return value.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`ReturnValue: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dialogElm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;returnValue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// programatically prevent the default button event and use the dialog close&lt;/span&gt;
&lt;span class="c1"&gt;// event, sending the value of the input field.&lt;/span&gt;
&lt;span class="nx"&gt;okButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
 &lt;span class="nx"&gt;dialogElm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nameInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next video shows how you can open the modal, fill in the inner form, close it using the confirmation button, and get the value of the input outside of it:&lt;/p&gt;


      
     

&lt;blockquote&gt;
&lt;p&gt;For a deeper dive into the intricacies of the &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; element, I suggest checking out &lt;a href="https://web.dev/building-a-dialog-component/" rel="noopener noreferrer"&gt;Adam Argyle’s post on web.dev&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Disclosure widget with &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Using &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt; allows the creation of collapsible sections of content with a summary that can be clicked to reveal or hide the details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;details&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;I will be the title of the content underneath&lt;span class="nt"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Whatever is written here will be hidden by default&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/details&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the video below we can see how clicking on the &lt;code&gt;&amp;lt;summary&amp;gt;&lt;/code&gt; content reveals the rest:&lt;/p&gt;


      
    

&lt;p&gt;Show and hide content with no JavaScript?!&lt;/p&gt;

&lt;p&gt;Is this magic?!&lt;/p&gt;

&lt;p&gt;No. It’s part of the platform.&lt;/p&gt;

&lt;p&gt;You can also control the open/close state with JS, but the beauty is you don’t have to. In order to render an open widget, one can add an &lt;code&gt;open&lt;/code&gt; attribute to the &lt;code&gt;&amp;lt;details&amp;gt;&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;Notice that we do get some browser default styles like the triangle on the left.&lt;/p&gt;

&lt;p&gt;If we wanted to change styles we could use the &lt;code&gt;list-style&lt;/code&gt; CSS property to change the triangle and the &lt;code&gt;details[open]&lt;/code&gt; selector to change the content styles based on the open state.&lt;/p&gt;

&lt;p&gt;Check out a working example of these elements below:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/rNQXPqe?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Native autocomplete with &lt;code&gt;&amp;lt;datalist&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Did you know that your browser has an element that basically gives you an autocomplete with no JavaScript?&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;&amp;lt;datalist&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;option&amp;gt;&lt;/code&gt;, and an &lt;code&gt;&amp;lt;input&amp;gt;&lt;/code&gt; element is all you need!&lt;/p&gt;

&lt;p&gt;Check it out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"ice-cream-choice"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Choose a flavor:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;list=&lt;/span&gt;&lt;span class="s"&gt;"ice-cream-flavors"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"ice-cream-choice"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"ice-cream-choice"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;datalist&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"ice-cream-flavors"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Chocolate"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Coconut"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Mint"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Strawberry"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Vanilla"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/datalist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will show us an input in which, when we start typing, will give us suggestions:&lt;/p&gt;


      
    

&lt;p&gt;The bonus is that we get keyboard controls for the suggestions, and easily navigate through the list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Value bars with &lt;code&gt;&amp;lt;meter&amp;gt;&lt;/code&gt; / &lt;code&gt;&amp;lt;progress&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;meter&amp;gt;&lt;/code&gt; is an HTML element that allows you to display a value within a predefined range. It's often used to show progress bars or levels. It accepts the following attributes: &lt;code&gt;value&lt;/code&gt;, &lt;code&gt;min&lt;/code&gt;, &lt;code&gt;max&lt;/code&gt;, &lt;code&gt;low&lt;/code&gt;, &lt;code&gt;high&lt;/code&gt;, and &lt;code&gt;optimum&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With these attributes, we can indicate to the browser what the color of the bar would be, depending on the values.&lt;/p&gt;

&lt;p&gt;This is best understood through an example. Let’s take this fuel level example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"fuel"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Fuel level:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;meter&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"fuel"&lt;/span&gt;
       &lt;span class="na"&gt;min=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;max=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt;
       &lt;span class="na"&gt;low=&lt;/span&gt;&lt;span class="s"&gt;"33"&lt;/span&gt; &lt;span class="na"&gt;high=&lt;/span&gt;&lt;span class="s"&gt;"66"&lt;/span&gt; &lt;span class="na"&gt;optimum=&lt;/span&gt;&lt;span class="s"&gt;"80"&lt;/span&gt;
       &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"70"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    at 70/100
&lt;span class="nt"&gt;&amp;lt;/meter&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;What you put between the opening and closing  tag does not display.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This results in the a green bar in the browser:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/Jjegxqy?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The bar is green because our value (70) is higher than the &lt;code&gt;high&lt;/code&gt; attribute, therefore, we get green.&lt;/p&gt;

&lt;p&gt;If we change the value to something lower than the &lt;code&gt;high&lt;/code&gt; value, for example, &lt;code&gt;60&lt;/code&gt; our bar will change its color to yellow, without needing to change any CSS:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/vYQobwr?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;And if we set the &lt;code&gt;value&lt;/code&gt; attribute to lower than the &lt;code&gt;low&lt;/code&gt; (33) value, that would result in a red bar:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/poQMGXJ?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Pretty neat, no?&lt;/p&gt;

&lt;h3&gt;
  
  
  Flipping colors
&lt;/h3&gt;

&lt;p&gt;Now, let’s say we want to display something that has the opposite definition, meaning, when we have more, it’s bad, and when we have less, it’s better.&lt;/p&gt;

&lt;p&gt;For example, let’s say we want to display how much space we have left on a hard drive. In order to do this, all we have to do is define our attributes opposite to what we did with the fuel example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"disc-space"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Disc space:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;meter&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"disc-space"&lt;/span&gt;
       &lt;span class="na"&gt;min=&lt;/span&gt;&lt;span class="s"&gt;"0"&lt;/span&gt; &lt;span class="na"&gt;max=&lt;/span&gt;&lt;span class="s"&gt;"1024"&lt;/span&gt;
       &lt;span class="na"&gt;low=&lt;/span&gt;&lt;span class="s"&gt;"750"&lt;/span&gt; &lt;span class="na"&gt;high=&lt;/span&gt;&lt;span class="s"&gt;"300"&lt;/span&gt;   
       &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"850"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/meter&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will result in a red bar:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/YzRmBoL?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;When we have more disc space (value is less than low, for example 650) we’ll get a green bar:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/XWyvOvN?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Using &lt;code&gt;&amp;lt;progress&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;progress&amp;gt;&lt;/code&gt; element differs from &lt;code&gt;&amp;lt;meter&amp;gt;&lt;/code&gt; only slightly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It only has 2 attributes: max + value (the minimum value is always 0).&lt;/li&gt;
&lt;li&gt;It only displays one color out of the box.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a simple example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;progress&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"70"&lt;/span&gt; &lt;span class="na"&gt;max=&lt;/span&gt;&lt;span class="s"&gt;"100"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;70 %&lt;span class="nt"&gt;&amp;lt;/progress&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/OJaKdKd?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;However the one cool feature about this element, is that if you omit all of the attributes, you get an animated loading bar with a blue ellipsis moving back and forward:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/eYQqXOd?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;When using this element, just remember that there are &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/progress#accessibility_concerns" rel="noopener noreferrer"&gt;some accessibility concerns&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Highlight text with &lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;As the name suggests, &lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt; can be used to mark/highlight text within a block of content. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;blockquote&amp;gt;&lt;/span&gt;
  It is a period of civil war. Rebel spaceships, striking from a hidden base,
  have won their first victory against the evil Galactic Empire. During the
  battle, &lt;span class="nt"&gt;&amp;lt;mark&amp;gt;&lt;/span&gt;Rebel spies managed to steal secret plans&lt;span class="nt"&gt;&amp;lt;/mark&amp;gt;&lt;/span&gt; to the Empire's
  ultimate weapon, the DEATH STAR, an armored space station with enough power to
  destroy an entire planet.
&lt;span class="nt"&gt;&amp;lt;/blockquote&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Will render with the words in the &lt;code&gt;&amp;lt;mark&amp;gt;&lt;/code&gt; tag as highlighted yellow:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/NWEQJKQ?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;One thing to note about accessibility is that in order for screen readers to announce “marked” content, you need to use CSS in combination with &lt;code&gt;:before&lt;/code&gt; and &lt;code&gt;:after&lt;/code&gt;pseudo elements, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;mark&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nt"&gt;mark&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;clip-path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;clip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;hidden&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;white-space&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;nowrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;mark&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;" [highlight start] "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;mark&lt;/span&gt;&lt;span class="nd"&gt;::after&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;" [highlight end] "&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Responsive image sources with &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;One of the most underrated HTML tags is the &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; element, which allows you to serve different images based on the user's device and screen size. This can greatly improve the loading speed and user experience of your website.&lt;/p&gt;

&lt;p&gt;To use the &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; tag, you just include multiple &lt;code&gt;&amp;lt;source&amp;gt;&lt;/code&gt; elements within the tag, each with a different image source and media query to determine when it should be displayed.&lt;/p&gt;

&lt;p&gt;Here's an example of how to use the &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;picture&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt; &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"image-large.jpg"&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"(min-width: 1200px)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt; &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"image-medium.jpg"&lt;/span&gt; &lt;span class="na"&gt;media=&lt;/span&gt;&lt;span class="s"&gt;"(min-width: 768px)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;source&lt;/span&gt; &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"image-small.jpg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"image-fallback.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;"Image"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/picture&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, the browser chooses the appropriate image source based on the user's device and screen size. The first &lt;code&gt;&amp;lt;source&amp;gt;&lt;/code&gt; element is used for devices with a minimum width of 1200 pixels, the second for devices with a minimum width of 768 pixels, and the third for all other devices.&lt;/p&gt;

&lt;p&gt;If the browser does not support the &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; tag, it will fallback to the &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; element (although, all major browsers have supported this for a few years now).&lt;/p&gt;

&lt;p&gt;By using the &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt; tag, you can optimize your images for different devices and improve your website's performance and user experience.&lt;/p&gt;

&lt;p&gt;Below we can see this in action, when we resize the window, the browser renders a different image:&lt;/p&gt;


      
    

&lt;p&gt;For more about image optimizations, I suggest checking out &lt;a href="https://www.builder.io/blog/fast-images" rel="noopener noreferrer"&gt;“Optimal Images in HTML”&lt;/a&gt; a post that &lt;a href="https://twitter.com/steve8708" rel="noopener noreferrer"&gt;Steve&lt;/a&gt; wrote a while back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fun with math and science (elements)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/MathML" rel="noopener noreferrer"&gt;MathML&lt;/a&gt; is an XML based language for describing mathematical notations.&lt;/p&gt;

&lt;p&gt;The gist of it is that there are many elements that you can use to display equations and “sciencey” stuff, in case you need to.&lt;/p&gt;

&lt;p&gt;I will not dive in too deeply here, as I probably lack the math knowledge to actually explain anything significant.&lt;/p&gt;

&lt;p&gt;It’s just pretty cool to know that you can use the &lt;code&gt;&amp;lt;math&amp;gt;&lt;/code&gt; element with a variety of other sub elements to do something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
  The infinite sum
  &lt;span class="nt"&gt;&amp;lt;math&lt;/span&gt; &lt;span class="na"&gt;display=&lt;/span&gt;&lt;span class="s"&gt;"block"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;mrow&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;munderover&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;mo&amp;gt;&lt;/span&gt;∑&lt;span class="nt"&gt;&amp;lt;/mo&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;mrow&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;mi&amp;gt;&lt;/span&gt;n&lt;span class="nt"&gt;&amp;lt;/mi&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;mo&amp;gt;&lt;/span&gt;=&lt;span class="nt"&gt;&amp;lt;/mo&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;mn&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/mn&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/mrow&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;mrow&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;mo&amp;gt;&lt;/span&gt;+&lt;span class="nt"&gt;&amp;lt;/mo&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;mn&amp;gt;&lt;/span&gt;∞&lt;span class="nt"&gt;&amp;lt;/mn&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/mrow&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/munderover&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;mfrac&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;mn&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/mn&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;msup&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;mi&amp;gt;&lt;/span&gt;n&lt;span class="nt"&gt;&amp;lt;/mi&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;mn&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/mn&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/msup&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/mfrac&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/mrow&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/math&amp;gt;&lt;/span&gt;
  is equal to the real number
  &lt;span class="nt"&gt;&amp;lt;math&lt;/span&gt; &lt;span class="na"&gt;display=&lt;/span&gt;&lt;span class="s"&gt;"inline"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;mfrac&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;msup&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;mi&amp;gt;&lt;/span&gt;π&lt;span class="nt"&gt;&amp;lt;/mi&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;mn&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/mn&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/msup&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;mn&amp;gt;&lt;/span&gt;6&lt;span class="nt"&gt;&amp;lt;/mn&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/mfrac&amp;gt;&amp;lt;/math&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;.
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which would render this:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/dyQxrym?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Yeah science!
&lt;/h3&gt;


      
    

&lt;p&gt;With the &lt;code&gt;&amp;lt;sub&amp;gt;&lt;/code&gt; element you can do stuff like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
  Almost every developer's favorite molecule is
  C&lt;span class="nt"&gt;&amp;lt;sub&amp;gt;&lt;/span&gt;8&lt;span class="nt"&gt;&amp;lt;/sub&amp;gt;&lt;/span&gt;H&lt;span class="nt"&gt;&amp;lt;sub&amp;gt;&lt;/span&gt;10&lt;span class="nt"&gt;&amp;lt;/sub&amp;gt;&lt;/span&gt;N&lt;span class="nt"&gt;&amp;lt;sub&amp;gt;&lt;/span&gt;4&lt;span class="nt"&gt;&amp;lt;/sub&amp;gt;&lt;/span&gt;O&lt;span class="nt"&gt;&amp;lt;sub&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/sub&amp;gt;&lt;/span&gt;, which is commonly known
  as "caffeine."
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which would yield this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F521855c6a4f3417b8186c73c4f26f711%3Fwidth%3D758" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F521855c6a4f3417b8186c73c4f26f711%3Fwidth%3D758" alt="a screenshot of a text paragraph that has the correct molecular notation for caffeine." width="758" height="77"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This can come in handy for your chemistry website, or if you want to add footnotes.&lt;/p&gt;

&lt;p&gt;Some more useful elements are &lt;code&gt;&amp;lt;sup&amp;gt;&lt;/code&gt; which can be combined with &lt;code&gt;&amp;lt;var&amp;gt;&lt;/code&gt; to show off your algebra:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;The &lt;span class="nt"&gt;&amp;lt;em&amp;gt;&lt;/span&gt;Pythagorean theorem&lt;span class="nt"&gt;&amp;lt;/em&amp;gt;&lt;/span&gt; is often expressed as the following equation:&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&amp;lt;var&amp;gt;&lt;/span&gt;a&lt;span class="nt"&gt;&amp;lt;sup&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/sup&amp;gt;&amp;lt;/var&amp;gt;&lt;/span&gt; + &lt;span class="nt"&gt;&amp;lt;var&amp;gt;&lt;/span&gt;b&lt;span class="nt"&gt;&amp;lt;sup&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/sup&amp;gt;&amp;lt;/var&amp;gt;&lt;/span&gt; = &lt;span class="nt"&gt;&amp;lt;var&amp;gt;&lt;/span&gt;c&lt;span class="nt"&gt;&amp;lt;sup&amp;gt;&lt;/span&gt;2&lt;span class="nt"&gt;&amp;lt;/sup&amp;gt;&amp;lt;/var&amp;gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which would render this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fbc0c5f81937f45a79d5a16dc72ae2ad8%3Fwidth%3D296" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fbc0c5f81937f45a79d5a16dc72ae2ad8%3Fwidth%3D296" alt="text with superscript and variable tags used to illustrate the Pythagorean theorem" width="296" height="98"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But you could also use &lt;code&gt;&amp;lt;sup&amp;gt;&lt;/code&gt; to add ordinal numbers, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;
  The ordinal number "fifth" can be abbreviated in various languages as follows:
&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;English: 5&lt;span class="nt"&gt;&amp;lt;sup&amp;gt;&lt;/span&gt;th&lt;span class="nt"&gt;&amp;lt;/sup&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;French: 5&lt;span class="nt"&gt;&amp;lt;sup&amp;gt;&lt;/span&gt;ème&lt;span class="nt"&gt;&amp;lt;/sup&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which gives this result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fe05e7865be73491ebe81b37296a472e3%3Fwidth%3D788" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fe05e7865be73491ebe81b37296a472e3%3Fwidth%3D788" alt="text with superscript and variable tags used to illustrate the Pythagorean theorem" width="788" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or superior lettering (not sure what that is for, but you can), like for certain French abbreviations (apparently, as &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/sup#superior_lettering" rel="noopener noreferrer"&gt;I’ve learned from MDN&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Robert a présenté son rapport à M&lt;span class="nt"&gt;&amp;lt;sup&amp;gt;&lt;/span&gt;lle&lt;span class="nt"&gt;&amp;lt;/sup&amp;gt;&lt;/span&gt; Bernard.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That would render:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fbba074371a994480b434796ef46e5498%3Fwidth%3D788" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Fbba074371a994480b434796ef46e5498%3Fwidth%3D788" alt="text with superscript and variable tags used to illustrate the Pythagorean theorem" width="788" height="142"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Moaaaaaar elements!
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;You can show text diffing with &lt;code&gt;&amp;lt;del&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;ins&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You can use &lt;code&gt;&amp;lt;kbd&amp;gt;&lt;/code&gt; to show textual user input from a keyboard, voice input, or any other text entry device.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;abbr&amp;gt;&lt;/code&gt; is used to provide an abbreviation or acronym for a term.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;&amp;lt;cite&amp;gt;&lt;/code&gt; to, well, cite creative work.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;&amp;lt;bdi&amp;gt;&lt;/code&gt; element can help contain text when you need to isolate bi-directional text, for example mixing a left-to-right (LTR) language with a right-to-left (RTL).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In conclusion, HTML has a wide variety of elements that can help you create rich and interactive web pages. From the lesser-known elements like &lt;code&gt;&amp;lt;dialog&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;picture&amp;gt;&lt;/code&gt;, to the more commonly used elements like &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt;, each element provides unique functionality that can help you create a great user experience on your website. By taking advantage of these elements, you can make your website more accessible, more performant, and more engaging for your users.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" width="405" height="143"&gt;&lt;/a&gt;&lt;br&gt;
      &lt;br&gt;
    &lt;/p&gt;

&lt;p&gt;Visually build with your components&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;Builder.io&lt;/a&gt; is a headless CMS that lets you &lt;a href="https://www.builder.io/m/products" rel="noopener noreferrer"&gt;drag and drop&lt;/a&gt; with &lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;&lt;strong&gt;your&lt;/strong&gt; components&lt;/a&gt; right within your existing site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://builder.io/signup" rel="noopener noreferrer"&gt;Try it out&lt;/a&gt; &lt;a href="https://dev.to/m/developers"&gt;Learn more&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Dynamically render your components&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;MyPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="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;BuilderComponent&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;registerComponents&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;MyHero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyProducts&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  &lt;em&gt;Read the &lt;a href="https://www.builder.io/blog/powerful-html-tags" rel="noopener noreferrer"&gt;full post&lt;/a&gt; on the &lt;a href="https://www.builder.io/blog" rel="noopener noreferrer"&gt;Builder.io blog&lt;/a&gt;&lt;/em&gt;
&lt;/h5&gt;

</description>
      <category>webdev</category>
      <category>html</category>
      <category>frontend</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Closing the Gap: Simplify Your Web Layouts with the CSS Gap Property</title>
      <dc:creator>Yoav Ganbar</dc:creator>
      <pubDate>Thu, 10 Aug 2023 09:21:34 +0000</pubDate>
      <link>https://dev.to/builderio/closing-the-gap-simplify-your-web-layouts-with-the-css-gap-property-46oa</link>
      <guid>https://dev.to/builderio/closing-the-gap-simplify-your-web-layouts-with-the-css-gap-property-46oa</guid>
      <description>&lt;p&gt;As a web developer, you're always looking for ways to improve your code and make your layouts more efficient.&lt;/p&gt;

&lt;p&gt;One such improvement is the CSS Gap Property, which can simplify your web layouts and make them more visually appealing. Let’s explore the benefits of using the CSS Gap Property instead of margins, and how it can make your life as a developer easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Margin is spacing&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Like a lot of things in software development, there are opposing opinions and camps for certain mehods and preferences. One of these cases is the use of CSS margin, either using only &lt;code&gt;margin-top&lt;/code&gt; or using &lt;code&gt;margin-bottom&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Nowadays, it’s better to use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_logical_properties_and_values" rel="noopener noreferrer"&gt;CSS logical properties and values&lt;/a&gt;, but the question of which strategy to use is only an opinion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Go with the flow
&lt;/h3&gt;

&lt;p&gt;As many of you may know, the natural flow (or &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Normal_Flow" rel="noopener noreferrer"&gt;normal flow&lt;/a&gt;) of the DOM is top to bottom. That is to say, any block element will be placed below the preceding block and any inline block will be inline.&lt;/p&gt;

&lt;p&gt;Check out the following example to better understand this concept:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/preview/BaGEZbJ?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;That is why a lot of &lt;a href="https://css-tricks.com/margin-bottom-margin-top/" rel="noopener noreferrer"&gt;front end developers might prefer using margin-bottom&lt;/a&gt; as it feels more natural.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The CSS gap property: an overview&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/gap" rel="noopener noreferrer"&gt;CSS Gap Property&lt;/a&gt; provides several benefits to web developers looking to create visually appealing and organized web layouts. It simplifies layouts, improves readability, enables responsive design, reduces code complexity, and improves browser performance. The Gap Property defines the size of the gap between the rows and columns in &lt;code&gt;flexbox&lt;/code&gt;, &lt;code&gt;grid&lt;/code&gt;, or multi-column layouts. It is a shorthand for the &lt;code&gt;row-gap&lt;/code&gt; and &lt;code&gt;column-gap&lt;/code&gt; properties.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of using gap instead of margin
&lt;/h3&gt;

&lt;p&gt;Using the CSS gap property instead of margins has several advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Simplifies layouts&lt;/strong&gt; : Previously, developers had to use margin or padding to create space between elements, which could be time-consuming and result in inconsistent layouts. The CSS Gap Property eliminates this problem by providing a simple and efficient way to add space between elements without affecting their dimensions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easier responsive design&lt;/strong&gt; : Gap makes it easier to handle spacing in responsive designs without the need for complex calculations or additional wrapper elements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced code complexity&lt;/strong&gt; : Instead of using multiple CSS properties to create space between elements, you can use the CSS gap property to achieve the same effect with a single line of code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better browser performance&lt;/strong&gt; : The CSS gap property can improve the performance of your website by reducing the amount of code required to create space between elements. This can result in faster load times and better overall performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No need for negative margins or pseudo selectors&lt;/strong&gt; : Using the gap property doesn't require thinking about negative margins or using pseudo selectors to remove first or last element margins.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://twitter.com/Steve8708" rel="noopener noreferrer"&gt;Steve&lt;/a&gt; explains this quite well in this video:&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/86CjEllFLp0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;﻿Gap versus margin: a visual comparison&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To better illustrate the differences between using the CSS gap property and margins, let's consider a minimal example with a flexbox layout:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Using Margin:&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"margin-example"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Box 1&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Box 2&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Box 3&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Box 4&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.margin-example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;flex-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.margin-example&lt;/span&gt; &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rebeccapurple&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.margin-example&lt;/span&gt; &lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="nd"&gt;:first-child&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nc"&gt;.margin-example&lt;/span&gt; &lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="nd"&gt;:last-child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&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;Here’s the result:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/preview/GRwLYPK?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Depending on what device you are viewing this from, this might look broken to you, and you would be right. The corresponding margin code from above is only taking into account desktop sizes, and is adding (margin) spacing to the left.&lt;/p&gt;

&lt;p&gt;As a result, the mobile display is broken, as can be inferred from the image below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F6f60f25f72a94c2cb7061507ab2c3c19%3Fwidth%3D705" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F6f60f25f72a94c2cb7061507ab2c3c19%3Fwidth%3D705" alt="screenshot of bad margin spacing." width="705" height="675"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How can we fix this? We could add a media query to handle what happens on mobile sizes. The naive approach would be to just switch up the &lt;code&gt;margin-left&lt;/code&gt; &amp;amp; &lt;code&gt;margin-right&lt;/code&gt; to &lt;code&gt;margin-top&lt;/code&gt; &amp;amp; &lt;code&gt;margin-bottom&lt;/code&gt; values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;425px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c"&gt;/* CSS styles for mobile devices */&lt;/span&gt;
 &lt;span class="nc"&gt;.margin-example&lt;/span&gt; &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="m"&gt;0&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;The result:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/preview/xxQeMvy?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;That still isn’t right, is it?&lt;/p&gt;

&lt;p&gt;It’s also clunky in different screen sizes when we resize the viewport window as can be seen below:&lt;/p&gt;


      
    

&lt;p&gt;When we get to our media query breakpoint things go awry. Suddenly, boxes change sizes, and when we do get to more of our mobile screen size our second and third box get more space between them than we might have expected.&lt;/p&gt;

&lt;p&gt;We’d need to do more work to make the responsiveness right.&lt;/p&gt;

&lt;h3&gt;
  
  
  ﻿ &lt;strong&gt;Same example using gap:&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;section&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"gap-example"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Box 1&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Box 2&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Box 3&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Box 4&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.gap-example&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;flex-wrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;wrap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.gap-example&lt;/span&gt; &lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rebeccapurple&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&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;First off, using the CSS gap property results in cleaner and more concise code compared to using margins.&lt;/p&gt;

&lt;p&gt;What about responsiveness? Have a look:&lt;/p&gt;


      
    

&lt;p&gt;Responsive without hassle!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Embracing the Gap: A Practical Example&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let's say you have a grid layout with multiple elements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;section&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Box 1&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Box 2&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Box 3&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Box 4&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create a responsive design and add space between the elements, you can use the CSS gap property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;section&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auto-fit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;200px&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;This will create a &lt;code&gt;20px&lt;/code&gt; gap between the rows and columns, making the layout more visually appealing and easier to manage:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hamatoyogi/embed/preview/QWJPoox?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The CSS gap property is a powerful tool that can simplify your web layouts and make them more visually appealing. By using the gap property instead of margins, you can reduce code complexity, improve browser performance, and create more consistent and responsive designs. So, the next time you're working on a web layout, consider using the CSS Gap Property to make your life as a developer easier and your layouts more efficient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" width="405" height="143"&gt;&lt;/a&gt;&lt;br&gt;
      &lt;br&gt;
    &lt;/p&gt;

&lt;p&gt;Visually build with your components&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;Builder.io&lt;/a&gt; is a headless CMS that lets you &lt;a href="https://www.builder.io/m/products" rel="noopener noreferrer"&gt;drag and drop&lt;/a&gt; with &lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;&lt;strong&gt;your&lt;/strong&gt; components&lt;/a&gt; right within your existing site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://builder.io/signup" rel="noopener noreferrer"&gt;Try it out&lt;/a&gt; &lt;a href="https://dev.to/m/developers"&gt;Learn more&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Dynamically render your components&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;MyPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="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;BuilderComponent&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;registerComponents&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;MyHero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyProducts&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  &lt;em&gt;Read the &lt;a href="https://www.builder.io/blog/css-gap" rel="noopener noreferrer"&gt;full post&lt;/a&gt; on the &lt;a href="https://www.builder.io/blog" rel="noopener noreferrer"&gt;Builder.io blog&lt;/a&gt;&lt;/em&gt;
&lt;/h5&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>learning</category>
      <category>frontend</category>
    </item>
    <item>
      <title>UI over APIs</title>
      <dc:creator>Yoav Ganbar</dc:creator>
      <pubDate>Fri, 04 Aug 2023 05:16:20 +0000</pubDate>
      <link>https://dev.to/builderio/ui-over-apis-4bf3</link>
      <guid>https://dev.to/builderio/ui-over-apis-4bf3</guid>
      <description>&lt;p&gt;One technique that is changing the way we think about user interfaces (UIs) is sending UIs over APIs, also known as server-driven UIs. This approach offers a new level of dynamism and flexibility that is transforming the traditional paradigms of UI development.&lt;/p&gt;

&lt;p&gt;Server-driven UIs are not just a theoretical concept; they are being implemented by some of the biggest names in the tech industry. Instagram, &lt;a href="https://eng.lyft.com/the-journey-to-server-driven-ui-at-lyft-bikes-and-scooters-c19264a0378e" rel="noopener noreferrer"&gt;Lyft&lt;/a&gt;, and &lt;a href="https://medium.com/airbnb-engineering/a-deep-dive-into-airbnbs-server-driven-ui-system-842244c5f5" rel="noopener noreferrer"&gt;Airbnb&lt;/a&gt; for instance, have been part of this movement, leveraging server-driven UIs to deliver dynamic content and updates to millions of users worldwide.&lt;/p&gt;

&lt;p&gt;But what exactly are server-driven UIs? How do they work, and why are they becoming so important in modern JavaScript development? This blog post aims to answer these questions and provide an in-depth look at server-driven UIs, their benefits, and how you can implement them in your own projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Understanding server-driven UIs&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Server-driven UIs represent a new approach to UI development. They offer a dynamic and flexible way to generate UIs on the server and send them to the client through APIs. This approach can provide faster iteration and more personalized user experiences.&lt;/p&gt;

&lt;p&gt;While there are challenges to consider, such as app store guidelines and offline user experience management, server-driven UIs offer an exciting direction for the future of UI development.&lt;/p&gt;

&lt;p&gt;In contrast, server-driven UIs are dynamically generated on the server and sent to the client via APIs. The server sends a JSON representation of the UI, which the client then renders. This means that the UI can be updated on the server side without requiring any changes to the client.&lt;/p&gt;

&lt;p&gt;The UI becomes dynamic and flexible, capable of changing in real-time based on various factors such as user behavior, A/B testing results, or new feature rollouts. &lt;a href="http://Builder.io" rel="noopener noreferrer"&gt;Builder.io&lt;/a&gt; for example, uses this approach in its framework SDKs by providing a component that can accept the JSON as an input and render designs that were built visually:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BuilderComponent&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;@builder.io/react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&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;MyPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;params&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;builderJSON&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;
    &lt;span class="c1"&gt;// Get the page content JSON from Builder with the specified options&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;page&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="na"&gt;userAttributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Use the page path specified in the URL to fetch the content&lt;/span&gt;
        &lt;span class="na"&gt;urlPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="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="p"&gt;(&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;YourHeader&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BuilderComponent&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;builderJSON&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;page&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;YourFooter&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach has several advantages over traditional UI development. For one, it allows for faster iteration, as changes can be made on the server side and immediately reflected on the client. It also enables backend developers to contribute to frontend development, as they can define the UI structure and behavior on the server.&lt;/p&gt;

&lt;p&gt;However, server-driven UIs are not without their challenges. They require a different way of thinking about UI development, and there are technical considerations to take into account, such as how to handle actions and maintain a smooth user experience. But with careful planning and implementation, these challenges can be overcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Role of server-driven UIs in Instagram&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Instagram's adoption of server-driven UIs provides a compelling case study of this innovative approach in action. The social media giant has developed a technology called "blocks" that leverages the concept of server-driven UIs to deliver dynamic content and updates to its users.&lt;/p&gt;

&lt;p&gt;Steve Sewell,CEO @ &lt;a href="http://builder.io/" rel="noopener noreferrer"&gt;Builder.io&lt;/a&gt;, and Yaser Alkayale, engineer @ Instagram/Meta, had a conversation about Sending UIs over APIs:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/uL-grjeYc18"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;In Instagram's implementation, the server sends a tree-like structure of blocks to the client. Each block represents a part of the UI and contains information about what component to render and what props to pass to that component. The client then traverses this tree structure, rendering the components as specified by the blocks.&lt;/p&gt;

&lt;p&gt;This approach allows Instagram to make immediate updates to the UI without needing to push a new version of the app. For example, if a bug is found in a particular UI component, the server can simply stop sending blocks that render that component, effectively fixing the bug for all users instantly.&lt;/p&gt;

&lt;p&gt;Moreover, server-driven UIs have enabled Instagram to iterate faster on its product. Instead of waiting for a new app version to be released, product teams can make changes to the UI on the server and see those changes reflected in the app immediately. This has led to a more agile and responsive product development process.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The benefits of server-driven UIs&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The adoption of server-driven UIs brings a host of benefits that can significantly enhance the development process and the end-user experience.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Immediate bug fixes and faster iteration&lt;/strong&gt; : As demonstrated by Instagram's use case, one of the most significant advantages is the ability to make immediate bug fixes and faster iterations. Changes to the UI can be made on the server side and reflected instantly on the client side, without the need for users to update their app or for developers to go through a lengthy app store review process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend developers contribute to frontend development&lt;/strong&gt; : Server-driven UIs also blur the line between frontend and backend development. Backend developers can define the UI structure and behavior on the server, allowing them to contribute more directly to the frontend development process. This can lead to more efficient use of resources and a more cohesive development team.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic and personalized user experiences&lt;/strong&gt; : With server-driven UIs, the user experience can be dynamically tailored based on a variety of factors. For example, the server could send different UIs based on the user's behavior, preferences, or even A/B testing results. This can lead to more personalized and engaging user experiences.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reduced client complexity&lt;/strong&gt; : By moving much of the UI logic to the server, server-driven UIs can also reduce the complexity of the client. This can make the client lighter and faster, leading to improved performance and a smoother user experience.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Building server-driven UIs: a practical guide&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Building server-driven UIs may seem daunting at first, but with a clear understanding of the process and some practical steps, it can be a manageable and rewarding endeavor. Here's a step-by-step guide on how to build server-driven UIs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a tree structure&lt;/strong&gt; : The first step in building a server-driven UI is to create a tree-like structure that represents your UI. Each node in the tree corresponds to a UI component and contains information about what component to render and what props to pass to that component.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle actions&lt;/strong&gt; : Actions, such as user interactions, need to be handled in a server-driven UI. This can be done by including action handlers in your components that send requests to the server. The server can then respond with a new UI tree based on the action.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use JSON format&lt;/strong&gt; : The UI tree is typically represented in a JSON format, which can be easily sent over an API and parsed by the client.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement a rendering engine&lt;/strong&gt; : On the client side, you'll need a rendering engine that can traverse the UI tree and render the components as specified by the tree.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test and iterate&lt;/strong&gt; : As with any development process, testing and iteration are key. Be sure to thoroughly test your server-driven UI and make improvements based on your findings.
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252Ffa850b036bb84af6a8a4b1a474250c06%3Fwidth%3D705" alt="Untitled" width="705" height="978"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remember, building server-driven UIs requires a shift in mindset from traditional UI development. It's not just about coding, but also about architecting your UI in a way that can be dynamically generated and updated from the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Navigating the challenges of server-driven UIs&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;While server-driven UIs open up new possibilities for UI development, they also introduce new considerations that developers need to be aware of:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;App store guidelines&lt;/strong&gt; : App stores have guidelines that need to be followed. It's important to ensure that your use of server-driven UIs aligns with these guidelines. Transparency about your UI approach when submitting your app for review can help avoid any potential issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline user experience&lt;/strong&gt; : Since server-driven UIs depend on server communication, managing the user experience when offline can be a challenge. Implementing strategies like caching can help maintain a consistent user experience even without a network connection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance considerations&lt;/strong&gt; : While server-driven UIs offer dynamic capabilities, there can be performance considerations to keep in mind. Efficient network requests and optimized rendering techniques can help maintain a smooth user experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Added complexity&lt;/strong&gt; : Implementing server-driven UIs can add a layer of complexity to the development process, as UI management occurs on both the server and client side. However, with a well-structured approach and clear separation of responsibilities, this complexity can be effectively managed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;While these considerations present their own challenges, they also offer opportunities for problem-solving and innovation. With thoughtful planning and execution, server-driven UIs can be a valuable addition to your development toolkit.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Sending UIs over APIs, or server-driven UIs, represents a significant shift in the landscape of UI development. By moving much of the UI logic to the server, this approach offers a level of dynamism and flexibility that is reshaping the industry.&lt;/p&gt;

&lt;p&gt;From immediate bug fixes and faster iteration to enabling backend developers to contribute to frontend development, server-driven UIs bring a host of benefits. They also allow for more personalized and engaging user experiences, and can reduce the complexity of the client for improved performance.&lt;/p&gt;

&lt;p&gt;While there are challenges to navigate, such as app store guidelines and managing the offline experience, these can be effectively addressed with careful planning and strategic approaches.&lt;/p&gt;

&lt;p&gt;In the world of advanced JavaScript development, server-driven UIs are not just a theoretical concept, but a practical approach being adopted by major platforms like Instagram. As we continue to push the boundaries of what's possible in UI development, server-driven UIs offer an exciting direction for the future.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.builder.io%2Fapi%2Fv1%2Fimage%2Fassets%252FYJIGb4i01jvw0SRdL5Bt%252F83677fb912dd4a539a3f3bb5c0c82de1%3Fwidth%3D405" width="405" height="143"&gt;&lt;/a&gt;&lt;br&gt;
      &lt;br&gt;
    &lt;/p&gt;

&lt;p&gt;Visually build with your components&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;Builder.io&lt;/a&gt; is a headless CMS that lets you &lt;a href="https://www.builder.io/m/products" rel="noopener noreferrer"&gt;drag and drop&lt;/a&gt; with &lt;a href="https://www.builder.io/m/developers" rel="noopener noreferrer"&gt;&lt;strong&gt;your&lt;/strong&gt; components&lt;/a&gt; right within your existing site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://builder.io/signup" rel="noopener noreferrer"&gt;Try it out&lt;/a&gt; &lt;a href="https://dev.to/m/developers"&gt;Learn more&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Dynamically render your components&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;MyPage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="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;BuilderComponent&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;registerComponents&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;MyHero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;MyProducts&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  &lt;em&gt;Read the &lt;a href="https://www.builder.io/blog/ui-over-apis" rel="noopener noreferrer"&gt;full post&lt;/a&gt; on the &lt;a href="https://www.builder.io/blog" rel="noopener noreferrer"&gt;Builder.io blog&lt;/a&gt;&lt;/em&gt;
&lt;/h5&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>architecture</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
