<?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: Ravshan Hojimatov</title>
    <description>The latest articles on DEV Community by Ravshan Hojimatov (@hojimat).</description>
    <link>https://dev.to/hojimat</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%2F2610271%2Fbe8bbd94-1d22-4c85-9f55-dbe436ffb8a5.jpeg</url>
      <title>DEV Community: Ravshan Hojimatov</title>
      <link>https://dev.to/hojimat</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hojimat"/>
    <language>en</language>
    <item>
      <title>A no-nonsense guide to frontend for backend developers</title>
      <dc:creator>Ravshan Hojimatov</dc:creator>
      <pubDate>Thu, 02 Jan 2025 08:08:10 +0000</pubDate>
      <link>https://dev.to/hojimat/a-no-nonsense-guide-to-frontend-for-backend-developers-1hjj</link>
      <guid>https://dev.to/hojimat/a-no-nonsense-guide-to-frontend-for-backend-developers-1hjj</guid>
      <description>&lt;ul&gt;
  &lt;li&gt;Introduction&lt;/li&gt;
  &lt;li&gt;Absolute basics&lt;/li&gt;
  &lt;li&gt;Client-side vs. Server-side&lt;/li&gt;
  &lt;li&gt;Components&lt;/li&gt;
  &lt;li&gt;Frontend libraries&lt;/li&gt;
  &lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a id="introduction"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I am a backend developer... the usual kind... the kind that is good at math but terrible at aesthetics. Any attempt at design that I ever made always resulted in boring looking generic junk. I tried using dozens of tools but the end result would always look like it was written in &lt;em&gt;Microsoft FrontPage 2003&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I was self-conscious enough to see that, so I gave up trying. I will write you a document, but only if you give me a ready $\LaTeX$ style file. I will write a blog, but only in &lt;em&gt;Markdown&lt;/em&gt; and let someone else worry about visual appeal. I will prepare a &lt;em&gt;DevFest&lt;/em&gt; presentation, but only if organizers provide a &lt;em&gt;PowerPoint template&lt;/em&gt;. I will never try to design anything, be it a button or a sign-in form.&lt;/p&gt;

&lt;p&gt;And yet, I cannot just shave my head and retreat to backend &lt;code&gt;JSON API&lt;/code&gt; sanctuary --- I still need to write frontend for my pet projects and build dashboards for internal use. But trying to enter the frontend world is incredibly painful --- dozens of frameworks, libraries, philosophies. I have been hearing the words &lt;code&gt;React&lt;/code&gt; or &lt;code&gt;Angular&lt;/code&gt; or &lt;code&gt;Node&lt;/code&gt; for the last 8 years but I was too scared to actually try and make sense of them. Learning &lt;code&gt;C++&lt;/code&gt; or &lt;em&gt;Leetcode&lt;/em&gt; has been easier than this.&lt;/p&gt;

&lt;p&gt;Nevertheless, I forced myself to learn it, and now I want to be a Prometheus (I am not sure if there isn't already a &lt;code&gt;JS&lt;/code&gt; framework with this name) and bring this knowledge to my people --- the backend devs.&lt;/p&gt;

&lt;p&gt;As a bonus, I included the ultimate recommendation of which frontend framework to choose. I myself had a decision paralysis for a very long time and this will help you overcome it and start building things without overthinking it. &lt;/p&gt;

&lt;p&gt;&lt;a id="absolute-basics"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Absolute basics
&lt;/h2&gt;

&lt;p&gt;Let's start with the absolute basics to ensure that we are on the same page before discussing frameworks. You can skip this section if you want.&lt;/p&gt;

&lt;h3&gt;
  
  
  Minimal web page
&lt;/h3&gt;

&lt;p&gt;A minimal web page consists of a text file with extension &lt;code&gt;.html&lt;/code&gt; and tags for content:&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;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Hello World!&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To add formatting you can either add a style attribute:&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;html&amp;gt;&lt;/span&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;"color:red; font-size:20px"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello World!&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or if you have a lot of formatting, add &lt;code&gt;id&lt;/code&gt; to your content and refer to it from &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; tag. The style is formatted using &lt;code&gt;CSS&lt;/code&gt; language which looks like an &lt;code&gt;HTML&lt;/code&gt; element followed by &lt;code&gt;JSON&lt;/code&gt; related to it:&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;html&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;"mytext"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello World&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;/* CSS code */&lt;/span&gt;
        &lt;span class="nf"&gt;#mytext&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;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;20pt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create static pages that do not change and do not react to any events. To add some interactivity, like checking if you left a form field empty or entered a valid email, you will need &lt;code&gt;JavaScript&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Running JavaScript
&lt;/h3&gt;

&lt;p&gt;Before using any programming language you must first install it on your computer. For &lt;code&gt;C/C++&lt;/code&gt; you need to install a compiler like &lt;code&gt;GCC&lt;/code&gt; or &lt;code&gt;Clang&lt;/code&gt;, for &lt;code&gt;Python&lt;/code&gt; you need to install a &lt;code&gt;CPython&lt;/code&gt; interpreter.&lt;/p&gt;

&lt;p&gt;To run &lt;code&gt;JavaScript&lt;/code&gt; you only need a web browser --- all modern web browsers can run &lt;code&gt;JS&lt;/code&gt; code. It is as simple as opening a web browser and going to pressing &lt;code&gt;F12&lt;/code&gt;. This will open a &lt;code&gt;JS&lt;/code&gt; console:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo1spy6mnzkpgkpyzh7vq.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo1spy6mnzkpgkpyzh7vq.png" alt="Image description" width="389" height="143"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also create a text file with extension &lt;code&gt;.html&lt;/code&gt;  and put a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag on it, open this file in browser, and the outcome will be displayed if you press &lt;code&gt;F12&lt;/code&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="c"&gt;&amp;lt;!-- myfile.html --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;// write a JS code here&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;Hello World&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, for safety reasons, the browser console has no access to your file system and lacks some other features that would make it possible to use &lt;code&gt;JS&lt;/code&gt; to, at least, achieve the functionality of other scripting languages like &lt;code&gt;Python&lt;/code&gt; or &lt;code&gt;Ruby&lt;/code&gt;. So, there is a second way to run &lt;code&gt;JS&lt;/code&gt; code on your computer --- installing &lt;code&gt;Node.js&lt;/code&gt;. It is essentially a &lt;code&gt;JS&lt;/code&gt; interpreter which can do stuff like reading and writing files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//$ node&lt;/span&gt;
&lt;span class="c1"&gt;//Welcome to Node.js v23.3.0.&lt;/span&gt;
&lt;span class="c1"&gt;//Type ".help" for more information.&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Creating a new directory&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;gt;&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;mkdirSync&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_dir&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// access filesystem using fs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;Node.js&lt;/code&gt; you can run &lt;code&gt;JS&lt;/code&gt; code in the server or in your &lt;code&gt;Docker&lt;/code&gt; container without having to install a web browser. We will see below that this is very useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Classical stack
&lt;/h3&gt;

&lt;p&gt;Combining the sections above we can create a web page using the classical &lt;code&gt;HTML+CSS+JS&lt;/code&gt; setup.&lt;/p&gt;

&lt;p&gt;They can be combined in a single &lt;code&gt;.html&lt;/code&gt; file with 3 sections: content itself, styles, and 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;html&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- page HTML content here --&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;"mytext"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello World&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"sayHelloWorld()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Say Hello&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;/* page CSS styles here */&lt;/span&gt;
        &lt;span class="nf"&gt;#mytext&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;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;20pt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40pt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;// page JS scripts here&lt;/span&gt;
        &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sayHelloWorld&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;Hello World&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see that we have a button that triggers a function &lt;code&gt;sayHelloWorld()&lt;/code&gt;, which is defined inside  &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags and it has font size of &lt;code&gt;40pt&lt;/code&gt;, which is defined inside &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; tags.&lt;/p&gt;

&lt;p&gt;Also note that the comment symbols are different in all 3 sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;inside pure &lt;code&gt;HTML&lt;/code&gt; it is &lt;code&gt;&amp;lt;!-- --&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;inside &lt;code&gt;CSS&lt;/code&gt; it is &lt;code&gt;/* */&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;inside &lt;code&gt;JS&lt;/code&gt; it is &lt;code&gt;//&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This shows that the browser understands that these are 3 different languages. So, the usual practice is not to clutter &lt;code&gt;.html&lt;/code&gt; file too much and separate it into 3 files and call styles and scripts by file path:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;content.html&lt;/strong&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;html&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;"mytext"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello World&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"sayHelloWorld()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Say Hello&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- include styles --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/css"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"styles.css"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="c"&gt;&amp;lt;!-- include scripts --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"scripts.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;styles.css&lt;/strong&gt;&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="nf"&gt;#mytext&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;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="m"&gt;20pt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;40pt&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;scripts.js&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sayHelloWorld&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;Hello World&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;The biggest problem with this setup is that if you look at the &lt;code&gt;HTML&lt;/code&gt; element, for example, the &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;, you cannot know which style it has and which scripts are listening to it unless you look at the other two files. Similarly, if you look at the &lt;code&gt;.js&lt;/code&gt; file, you see a function &lt;code&gt;sayHelloWorld()&lt;/code&gt; but have no idea whether it is needed or not, or if some element is calling it or not, without looking at the &lt;code&gt;.html&lt;/code&gt; file. This goes against the so-called &lt;em&gt;Locality of Behavior&lt;/em&gt; principle.&lt;/p&gt;

&lt;p&gt;Anyway, this setup has been used on the Web for several decades.&lt;/p&gt;

&lt;p&gt;&lt;a id="client-server"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Client-side vs. Server-side
&lt;/h2&gt;

&lt;p&gt;Great! We have covered the basics. Now let's talk about the main dilemma that underlies all discussions regarding the choice of a frontend framework, and the architecture of your app in general. Before we start, let's clarify some terminology: &lt;em&gt;client-side&lt;/em&gt; means the browser or an app in which the users consume your content, and &lt;em&gt;server-side&lt;/em&gt; is usually the backend server that stores the login information, has access to database, and overall serves as the backbone of the entire app. Now we are ready to dive deeper.&lt;/p&gt;

&lt;h3&gt;
  
  
  Classical HTML generation
&lt;/h3&gt;

&lt;p&gt;In any non-trivial web app that displays any kind of data we will need a way to generate &lt;code&gt;HTML&lt;/code&gt; scripts automatically. Otherwise, whenever the data is updated, somebody will have to manually update the &lt;code&gt;HTML&lt;/code&gt; tags.&lt;/p&gt;

&lt;p&gt;Since &lt;code&gt;HTML&lt;/code&gt; is a simple text file, it can be easily created by any scripting language as a string. There are many libraries that do this. For example, with &lt;code&gt;Jinja2&lt;/code&gt; library we can write all elements of a list &lt;code&gt;mylist = [1,2,3,4,5]&lt;/code&gt; into table rows using a language that resembles &lt;code&gt;Python&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;table&amp;gt;
    {% for item in mylist %}
        &amp;lt;tr&amp;gt; &amp;lt;td&amp;gt; {{ item }} &amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt;
    {% endfor %}
&amp;lt;/table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, the browser would not understand this --- you will need to &lt;em&gt;render&lt;/em&gt; this &lt;code&gt;Jinja2&lt;/code&gt; script into actual &lt;code&gt;HTML&lt;/code&gt; by running special commands in &lt;code&gt;Python&lt;/code&gt;, which will render an &lt;code&gt;.html&lt;/code&gt; file:&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;table&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt; 1 &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt; 2 &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt; 3 &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt; 4 &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;tr&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt; 5 &lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/tr&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/table&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This feature is so crucial that it even has a special name --- &lt;em&gt;templating&lt;/em&gt;. I want to stress one thing: such &lt;code&gt;HTML&lt;/code&gt; generation from a template happens in the server in a language of your choice (&lt;code&gt;Python/Ruby/Java/C#&lt;/code&gt;), usually a language your backend code is written in. Browsers do not understand  these languages natively --- they only understand &lt;code&gt;JS&lt;/code&gt;, so we send them a pre-rendered &lt;code&gt;HTML&lt;/code&gt; file. This will become important later on. &lt;/p&gt;

&lt;h3&gt;
  
  
  JSON vs HTML API
&lt;/h3&gt;

&lt;p&gt;In the previous section we saw how backend can generate &lt;code&gt;HTML&lt;/code&gt; scripts and fill them with the data from database and other information. For example, if the user presses the &lt;em&gt;Like&lt;/em&gt; button on some social media post, the backend must update the content of &lt;em&gt;Liked Posts&lt;/em&gt; page to include that new post there. This can be done in two ways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1)&lt;/strong&gt; Backend has an &lt;code&gt;HTML&lt;/code&gt; template ready with some &lt;code&gt;Jinja2&lt;/code&gt; script and renders it with the latest query result from the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;table&amp;gt;
    {% for post in liked_posts %}
        &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;{{ post.author }}&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;{{ post.text }}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;
    {% endfor %}
&amp;lt;/table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the rendered &lt;code&gt;HTML&lt;/code&gt; is sent directly to the frontend together with the &lt;code&gt;CSS&lt;/code&gt; styles and &lt;code&gt;JS&lt;/code&gt; scripts. The browser simply displays what the backend has already prepared and is not aware of the types of data or any logic on the page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2)&lt;/strong&gt; Backend sends the &lt;code&gt;JSON&lt;/code&gt; that specifies the query result from database 's &lt;code&gt;liked_posts&lt;/code&gt; table in a format that browser would understand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;liked_posts:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;author:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Apple"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;text:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Think different"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;author:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Nike"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;text:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Just do it"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser runs special &lt;code&gt;JS&lt;/code&gt; functions that request such &lt;code&gt;JSON&lt;/code&gt;, and when they receive it, they use extract data from it and generate &lt;code&gt;HTML&lt;/code&gt; from it on the browser itself:&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;table&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"myTable"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/table&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;

    &lt;span class="c1"&gt;// Find the table&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;table&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;myTable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// For each entry in JSON add a row with two columns for author and text&lt;/span&gt;
    &lt;span class="nx"&gt;liked_posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&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;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt;
            &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;author&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Server-side rendering
&lt;/h3&gt;

&lt;p&gt;Note that in &lt;code&gt;JSON API&lt;/code&gt; architecture the browser knows a lot about the data it receives --- it sees the different fields, it can perform programming tasks on it like reversing strings, multiplying, repeating, reusing the author name in several places etc.&lt;/p&gt;

&lt;p&gt;This is really useful if you need a complex interactive user interface but this is slightly less secure because the browser is not in your hands --- it belongs to a user who can be malicious. &lt;/p&gt;

&lt;p&gt;Moreover, if the user's computer is weak, running all these scripts in the browser will slow down the entire web app, unlike pre-rendered &lt;code&gt;HTML&lt;/code&gt; which is a simple text file that will run smoothly in most computers.&lt;/p&gt;

&lt;p&gt;Also, the search engine crawlers do not usually wait for the web page to load all of its scripts, and if the page has zero content on it to begin with, the search engine optimization suffers as a result.&lt;/p&gt;

&lt;p&gt;There is a modern trend called &lt;em&gt;Server-side rendering (SSR)&lt;/em&gt; that runs &lt;code&gt;Node.js&lt;/code&gt; on the server and pre-renders some &lt;code&gt;HTML&lt;/code&gt; pages using &lt;code&gt;JS&lt;/code&gt; directly in the server. This kinda solves the problems above, but it also bites a slice of the backend's pie. If we try to visualize the three approaches, it would be something like this (assuming backend is in &lt;code&gt;Python&lt;/code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmi9t46lv3vzcc9fql7i.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmi9t46lv3vzcc9fql7i.png" alt="Image description" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In SSR the &lt;code&gt;Python&lt;/code&gt; backend has access to database and maybe stores login information, but everything else is done in &lt;code&gt;JS&lt;/code&gt;. The diagrams are very simplistic, but in SSR there is also &lt;code&gt;JS&lt;/code&gt; on the client side, making the entire web application 95% written in &lt;code&gt;JS&lt;/code&gt;. Some libraries took the next logical step and covered the entire backend in &lt;code&gt;JS&lt;/code&gt; using frameworks like &lt;code&gt;Express.js&lt;/code&gt;, but I won't be talking about the &lt;code&gt;JS&lt;/code&gt; backend in this article.&lt;/p&gt;

&lt;h3&gt;
  
  
  Build step
&lt;/h3&gt;

&lt;p&gt;These &lt;code&gt;JS&lt;/code&gt; scripts are usually not written manually but are compiled by some higher level &lt;code&gt;JS&lt;/code&gt; library or framework. This build step (i.e. compilation of higher level code into &lt;code&gt;HTML+JS&lt;/code&gt;) is done in server using a running &lt;code&gt;Node.js&lt;/code&gt; instance.&lt;/p&gt;

&lt;p&gt;By design, all the &lt;code&gt;JS&lt;/code&gt; dependencies are installed into a virtual environment (similar to &lt;code&gt;virtualenv&lt;/code&gt; in Python or &lt;code&gt;rbenv&lt;/code&gt; in Ruby) that is stored directly in the work folder in a subdirectory called &lt;code&gt;node_modules&lt;/code&gt;. It usually takes up around 200MB of space and should be &lt;code&gt;.gitignored&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once you run a build command that usually looks like &lt;code&gt;npm run build&lt;/code&gt;, it will generate the static &lt;code&gt;HTML+JS&lt;/code&gt; files. Now you have 2 options to serve these static files to the client's browser:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Using your backend's &lt;code&gt;FileResponse&lt;/code&gt; which simply scans for the generated files in the static directory, resolves the relative paths, and sends the files to the client.&lt;/li&gt;
&lt;li&gt;Using &lt;code&gt;Node.js&lt;/code&gt;'s  serve functionality like &lt;code&gt;npx serve mydir&lt;/code&gt; which will run a server in a separate port, independently from your backend.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Overall, it looks kinda like 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbn3t1da3e6ebgkm37e2j.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbn3t1da3e6ebgkm37e2j.png" alt="Image description" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Option 1 has a very intuitive setup --- you can bind your backend's router and respond to certain URLs with these files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;FileResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dist/index.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Option 2 is popular for some reason, although it is more complicated. In this setup you only expose the frontend port to the client, and it will serve the static &lt;code&gt;HTML+JS&lt;/code&gt; app without any need for the backend. And only when it needs to fetch data from the backend, will the frontend connect to the backend itself, abstracting away this functionality from the browser. Of course, to do so the frontend now will need its own router. Basically, this is frontend trying to do what backend should be doing.&lt;/p&gt;

&lt;p&gt;&lt;a id="components"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Components
&lt;/h2&gt;

&lt;p&gt;So far, we have covered the basics of how the working frontend code can be written and where it is located. We have seen how &lt;code&gt;HTML&lt;/code&gt; can be automatically generated but, up till now, we assumed that the &lt;code&gt;JS&lt;/code&gt; part is written manually. This is very often not the case in the real life frontend development. Manually writing &lt;code&gt;JS&lt;/code&gt; scripts is cumbersome and your code structure gets very messy very fast. Moreover, if you need to reuse scripts, you will have to old-school copy and paste them. So, since the very beginning, developers used some sorts of libraries to make &lt;code&gt;JS&lt;/code&gt; development easier and more structured.&lt;/p&gt;

&lt;h3&gt;
  
  
  JQuery
&lt;/h3&gt;

&lt;p&gt;In the early days, using vanilla &lt;code&gt;JS&lt;/code&gt; to find and modify elements or to send &lt;code&gt;AJAX&lt;/code&gt; requests to the server was very cumbersome. Thus, many developers used &lt;code&gt;JQuery&lt;/code&gt;, which was a neat syntactic sugar on top of the vanilla &lt;code&gt;JS&lt;/code&gt;. Many add-ons have been written in &lt;code&gt;JQuery&lt;/code&gt;, like &lt;code&gt;Datatables&lt;/code&gt; (interactive tables with search, pagination, sorting out of box), or animated clocks, or counters etc. Using such components pre-written by someone else was really easy --- just download the code and add it to your &lt;code&gt;HTML&lt;/code&gt; page under &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags. Revisiting the example from above, we could add a row to a table much easier with &lt;code&gt;JQuery&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="c1"&gt;// const table = document.getElementById('myTable');&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;$table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&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;#myTable&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;//  table.innerHTML += "abc";&lt;/span&gt;
    &lt;span class="nx"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;abc&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;or sending an &lt;code&gt;AJAX&lt;/code&gt; request to the backend API would require an entire separate library for vanilla &lt;code&gt;JS&lt;/code&gt; while it could be done easily in &lt;code&gt;JQuery&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ajax&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api.example.com&lt;/span&gt;&lt;span class="dl"&gt;'&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;GET&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;With time, though, vanilla &lt;code&gt;JS&lt;/code&gt; and &lt;code&gt;HTML&lt;/code&gt; standard itself added a lot of functionality, making &lt;code&gt;JQuery&lt;/code&gt; kinda obsolete. For example, pop-up calendars to select dates are built-in in HTML nowadays. Still, a lot of current web depends on &lt;code&gt;JQuery&lt;/code&gt; in one way or another.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bootstrap
&lt;/h3&gt;

&lt;p&gt;Around 2010, &lt;code&gt;Bootstrap&lt;/code&gt; was created as a library of reusable components, such as beautiful buttons, responsive forms, and pop-ups. The main feature of &lt;code&gt;Bootstrap&lt;/code&gt; was that it relied on the &lt;code&gt;HTML&lt;/code&gt; syntax, trying to minimize the time and energy the developers spend writing actual &lt;code&gt;JS&lt;/code&gt; code. It used &lt;code&gt;JQuery&lt;/code&gt; and &lt;code&gt;CSS&lt;/code&gt; under the hood, but it completely abstracted it away for its users. Basically, using &lt;code&gt;Bootstrap&lt;/code&gt; was as simple as adding classes to the &lt;code&gt;HTML&lt;/code&gt; elements.&lt;/p&gt;

&lt;p&gt;For example, you want to write a button which shows or hides a text when pressed. In &lt;code&gt;JS&lt;/code&gt; this looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- button itself --&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;"myButton"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Toggle Text&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- target text --&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;"text"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:none;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Example text here.
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;// find the button&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myButton&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;myButton&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// when the button is clicked:&lt;/span&gt;
    &lt;span class="nx"&gt;myButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclick&lt;/span&gt; &lt;span class="o"&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="c1"&gt;// find the target text with id=text&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;el&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;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// change display:none to display:block&lt;/span&gt;
            &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&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;block&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;none&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="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But in Bootstrap you do not write a single line of &lt;code&gt;JS&lt;/code&gt; yourself, just put the necessary classes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Button here targets #text and collapses it --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;data-bs-toggle=&lt;/span&gt;&lt;span class="s"&gt;"collapse"&lt;/span&gt; &lt;span class="na"&gt;data-bs-target=&lt;/span&gt;&lt;span class="s"&gt;"#text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Show/hide&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Text with id #text --&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;"collapse"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Example text 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;Bootstrap was a revolution in frontend development, and many libraries followed its approach, like &lt;code&gt;PicoCSS&lt;/code&gt; or &lt;code&gt;TailwindCSS&lt;/code&gt;. It super-powered the &lt;code&gt;HTML&lt;/code&gt; by just adding classes to it, but it couldn't create custom &lt;code&gt;HTML&lt;/code&gt; elements and had to rely on native &lt;code&gt;HTML&lt;/code&gt; 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="c"&gt;&amp;lt;!-- This will work --&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;"btn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Custom Button&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- This will not work, because HTML does not have &amp;lt;btn&amp;gt; element --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;btn&amp;gt;&lt;/span&gt;Custom Button&lt;span class="nt"&gt;&amp;lt;/btn&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means that you couldn't really create easy-to-use complex components like &lt;code&gt;&amp;lt;PieChart /&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;InteractiveTable /&amp;gt;&lt;/code&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  JSX and the likes
&lt;/h3&gt;

&lt;p&gt;Around the same time another approach to writing frontend appeared --- using scripting capabilities of &lt;code&gt;JS&lt;/code&gt; to develop components of any complexity and then simply compile them into &lt;code&gt;HTML&lt;/code&gt; (also known as the &lt;em&gt;Build step&lt;/em&gt;). To be able to do this, &lt;code&gt;React.js&lt;/code&gt; (and other similar libraries) found a way to write &lt;code&gt;HTML&lt;/code&gt; components inside the &lt;code&gt;JS&lt;/code&gt; code. There are multiple ways to do this, but I will show just one of them, called &lt;code&gt;JSX&lt;/code&gt;, which works like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// inside this JSX function we can write HTML and JS together&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&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="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt; &lt;span class="na"&gt;onclick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Custom Button&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;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and then use it inside a main &lt;code&gt;JSX&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; // custom component &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; defined in btn() function
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The web browser would not understand this &lt;code&gt;&amp;lt;btn&amp;gt;&lt;/code&gt; element, so the final step is to compile this &lt;code&gt;JSX&lt;/code&gt; code into &lt;code&gt;HTML+JS&lt;/code&gt;. The result will be something like:&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;id=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;// find root div, transform it using JS....&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The principle is very similar to compiling scripts to machine code. The end result will not be human-readable, and the resulting &lt;code&gt;HTML&lt;/code&gt; will contain lots of &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags instead of clear elements like &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt;. Below is a side-by-side comparison of the sources of Twitter (written in &lt;code&gt;React.js&lt;/code&gt;) and Basecamp (written in &lt;code&gt;HTML&lt;/code&gt; and a little bit of vanilla &lt;code&gt;JS&lt;/code&gt;). You can see which of them is easier to read and looks more like &lt;code&gt;HTML&lt;/code&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqd2y01g9wrsowfr1boxx.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqd2y01g9wrsowfr1boxx.png" alt="Image description" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are other alternatives to &lt;code&gt;JSX&lt;/code&gt;, which include &lt;code&gt;JS&lt;/code&gt; inside &lt;code&gt;HTML&lt;/code&gt; instead of including &lt;code&gt;HTML&lt;/code&gt; inside &lt;code&gt;JS&lt;/code&gt;, but in the end, all of them compile into the pile of non-human-readable scripts that somehow make browser-unsupported components work.&lt;/p&gt;

&lt;p&gt;By default, this pile of compiled &lt;code&gt;JS&lt;/code&gt; scripts is sent to browser, which then renders them. In the Server-Side rendering, the compiled scripts are compiled and rendered in the server, while the browser receives simple &lt;code&gt;HTML&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;As a reaction to the widespread component frameworks like &lt;code&gt;React.js&lt;/code&gt;, the Web standard has introduced a native way to create custom web components such as &lt;code&gt;&amp;lt;btn&amp;gt; &amp;lt;/btn&amp;gt;&lt;/code&gt; in the example above. Basically, the modern browsers will understand this &lt;code&gt;JS&lt;/code&gt; code where you define your &lt;code&gt;&amp;lt;my-btn&amp;gt;&lt;/code&gt; without any 3rd party frameworks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- use the custom my-btn --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;my-btn&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/my-btn&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// inherit HTMLElement&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Btn&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;HTMLElement&lt;/span&gt; &lt;span class="p"&gt;{...}&lt;/span&gt;
&lt;span class="c1"&gt;// define &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Btn&lt;/span&gt; &lt;span class="nx"&gt;above&lt;/span&gt;
&lt;span class="nx"&gt;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-btn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Btn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, this approach didn't really catch on yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  JS component libraries
&lt;/h3&gt;

&lt;p&gt;For those people who hesitate using libraries like &lt;code&gt;React.js&lt;/code&gt;, there are &lt;code&gt;JS&lt;/code&gt; libraries that provide pre-compiled components like &lt;code&gt;Chart.js&lt;/code&gt; which you can use to create charts with vanilla &lt;code&gt;JS&lt;/code&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="c"&gt;&amp;lt;!-- specify where to draw a chart --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;canvas&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"myChart"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/canvas&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;// find canvas&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;ctx&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;myChart&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// draw chart on canvas with data=[1,2,3]&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;myChart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Chart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&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;bar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;datasets&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]}]});&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is really helpful if you need an interactive chart but don't want to go fully into frontend &lt;code&gt;JS&lt;/code&gt; area. However, you will need to have your data in &lt;code&gt;JSON&lt;/code&gt; format, because such libraries usually do not read data from &lt;code&gt;HTML&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a id="frontend-libraries"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Frontend libraries
&lt;/h2&gt;

&lt;p&gt;Finally, let's have a very brief overview of the most popular frontend libraries and frameworks. By library we mean something that can render &lt;code&gt;JS&lt;/code&gt; and &lt;code&gt;HTML&lt;/code&gt; with custom components. By framework we mean everything in the library plus a frontend router and state management (i.e. ability to store global variables in the frontend). &lt;/p&gt;

&lt;h3&gt;
  
  
  React.js
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Brief summary:&lt;/em&gt;&lt;br&gt;
Uses &lt;code&gt;JSX&lt;/code&gt; to add &lt;code&gt;HTML&lt;/code&gt; into &lt;code&gt;JS&lt;/code&gt; functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello world!&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&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;which is not the most intuitive way to write dynamic pages.&lt;/p&gt;

&lt;p&gt;It is a library and supports numerous 3rd party tools for routing and state management. That is why it is too flexible and less intuitive for beginners.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Verdict:&lt;/em&gt; Not recommended.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vue.js
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Brief summary:&lt;/em&gt;&lt;br&gt;
Uses &lt;em&gt;templates&lt;/em&gt; to add &lt;code&gt;JS&lt;/code&gt; into &lt;code&gt;HTML&lt;/code&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;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&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;Hello, {{ name }}!&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which is very intuitive.&lt;/p&gt;

&lt;p&gt;It is a framework with &lt;code&gt;Vue Router&lt;/code&gt; for routing and &lt;code&gt;Pinia&lt;/code&gt; for state management. These are very often an overkill for backend developers, so keeping logic outside &lt;code&gt;Vue&lt;/code&gt; would be wise.&lt;/p&gt;

&lt;p&gt;It has a great community and ready-made component libraries for easily building stunning user interfaces --- &lt;code&gt;PrimeUI&lt;/code&gt; and &lt;code&gt;Vuetify&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Verdict:&lt;/em&gt; Recommended if you need beautiful UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Svelte
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Brief summary:&lt;/em&gt;&lt;br&gt;
A new kid in the block. Uses Single File Component system, where you write styles, scripts, and &lt;code&gt;HTML&lt;/code&gt; content in one file. Very easy to use.&lt;/p&gt;

&lt;p&gt;Uses &lt;em&gt;templates&lt;/em&gt; like &lt;code&gt;Vue.js&lt;/code&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;script&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;// define variable here&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;World&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Hello, {name}!&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;It is a minimal framework. And you will find yourself writing a lot of vanilla &lt;code&gt;JS&lt;/code&gt; code to achieve some functionality that is easy in &lt;code&gt;Vue.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Verdict:&lt;/em&gt; Not recommended.&lt;/p&gt;

&lt;h3&gt;
  
  
  Alpine.js
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Brief summary:&lt;/em&gt; a minimal library that has no build step --- the entire library is a single 15 KB &lt;code&gt;JS&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Uses &lt;em&gt;templates&lt;/em&gt; like &lt;code&gt;Vue.js&lt;/code&gt; and &lt;code&gt;Svelte&lt;/code&gt; but you can write &lt;code&gt;JS&lt;/code&gt; directly inside &lt;code&gt;HTML&lt;/code&gt; attributes without any &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- import library --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"//unpkg.com/alpinejs"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;x-data=&lt;/span&gt;&lt;span class="s"&gt;"{ name: 'World' }"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- define name here --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Hello, &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;x-text=&lt;/span&gt;&lt;span class="s"&gt;"name"&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;span class="c"&gt;&amp;lt;!-- use name here --&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;It markets itself as a modern replacement for &lt;code&gt;JQuery&lt;/code&gt; and it is really cool for adding a little bit of interactivity without a complicated user interface.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Verdict:&lt;/em&gt; Recommended if you need a little bit of interactivity and handling JSONs.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTMX
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Brief summary:&lt;/em&gt; a library that promotes having all logic in the backend and requesting &lt;code&gt;HTML&lt;/code&gt; instead of &lt;code&gt;JSON&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Promotes using any backend-side templating library like &lt;code&gt;Jinja2&lt;/code&gt; to generate required &lt;code&gt;HTML&lt;/code&gt; and then send this &lt;code&gt;HTML&lt;/code&gt; snippet to the client without any &lt;code&gt;JS&lt;/code&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;div&lt;/span&gt; &lt;span class="na"&gt;hx-get=&lt;/span&gt;&lt;span class="s"&gt;"/api/name"&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;
    &lt;span class="c"&gt;&amp;lt;!--
    sends a GET request to /api/name
    and puts whatever it receives
    inside this current div
    --&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;and the backend sends not a &lt;code&gt;JSON&lt;/code&gt; but an &lt;code&gt;HTML&lt;/code&gt; snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# on GET request to /api/name return HTML
&lt;/span&gt;&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/api/name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response_class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;HTMLResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;api_name&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;p&amp;gt;Hello, World!&amp;lt;/p&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;# instead of {"name": "World"}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Supports all &lt;code&gt;HTTP&lt;/code&gt; verbs (&lt;code&gt;GET/POST/PUT/PATCH/DELETE&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Verdict:&lt;/em&gt; Recommended if you don't need &lt;code&gt;JSON&lt;/code&gt; data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which framework to choose?
&lt;/h3&gt;

&lt;p&gt;I will try to be as simplistic and dismissive as possible, because if I went into an objective analysis of pros and cons, you wouldn't get any useful information aside from "it depends". I will be biased towards the least movements necessary to set up a user interface and to avoiding build step if possible. So, here is my ultimate recommendation:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yavg9tg5edy00jaeipd.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9yavg9tg5edy00jaeipd.png" alt="Image description" width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a id="conclusion"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;In this blog post I wanted to share everything that I learned about frontend as a backend developer. It seems that this stuff is overly complicated and intimidating, although, upon digging, I realized that there is a logic and structure to it. I hope that I could convey my understanding to you, and that you found this post useful.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>css</category>
    </item>
  </channel>
</rss>
