<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Md Mahbubur Rahman</title>
    <description>The latest articles on Forem by Md Mahbubur Rahman (@m-a-h-b-u-b).</description>
    <link>https://forem.com/m-a-h-b-u-b</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%2F3402651%2F75b461f2-dc1a-4556-88b5-10084232a266.png</url>
      <title>Forem: Md Mahbubur Rahman</title>
      <link>https://forem.com/m-a-h-b-u-b</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/m-a-h-b-u-b"/>
    <language>en</language>
    <item>
      <title>Create, Debug, and Publish Firefox Extensions: A Full Developer Guide Step by Step</title>
      <dc:creator>Md Mahbubur Rahman</dc:creator>
      <pubDate>Thu, 20 Nov 2025 04:31:34 +0000</pubDate>
      <link>https://forem.com/m-a-h-b-u-b/create-debug-and-publish-firefox-extensions-a-full-developer-guide-step-by-step-48ln</link>
      <guid>https://forem.com/m-a-h-b-u-b/create-debug-and-publish-firefox-extensions-a-full-developer-guide-step-by-step-48ln</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Why Firefox Extensions Matter&lt;/li&gt;
&lt;li&gt;Understanding WebExtensions Architecture&lt;/li&gt;
&lt;li&gt;Setting Up Your Development Environment&lt;/li&gt;
&lt;li&gt;Anatomy of a Firefox Extension&lt;/li&gt;
&lt;li&gt;Creating Your First Extension&lt;/li&gt;
&lt;li&gt;Background Scripts&lt;/li&gt;
&lt;li&gt;Content Scripts&lt;/li&gt;
&lt;li&gt;Popup &amp;amp; Options Page UI&lt;/li&gt;
&lt;li&gt;Messaging and Event Handling&lt;/li&gt;
&lt;li&gt;Storage and Data Management&lt;/li&gt;
&lt;li&gt;Permissions and Security Best Practices&lt;/li&gt;
&lt;li&gt;Intermediate Features&lt;/li&gt;
&lt;li&gt;Advanced Features&lt;/li&gt;
&lt;li&gt;Debugging and Troubleshooting&lt;/li&gt;
&lt;li&gt;Publishing on AMO&lt;/li&gt;
&lt;li&gt;Common Mistakes&lt;/li&gt;
&lt;li&gt;Performance Optimization&lt;/li&gt;
&lt;li&gt;Real-World Example: Text Saver Extension&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;Developing a Firefox extension empowers you to customize, automate, and enhance the browsing experience. Unlike traditional web apps, extensions can modify pages in real-time, interact with browser APIs, and provide tools that millions of users can rely on. Firefox supports the WebExtensions API, making it compatible across Chrome, Edge, and Opera, allowing portability of skills and code.&lt;/p&gt;

&lt;p&gt;This guide takes you from beginner concepts to advanced techniques. By the end, you will understand how to structure, code, debug, optimize, and publish Firefox extensions, all in a professional, human-written style.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Why Firefox Extensions Matter
&lt;/h2&gt;

&lt;p&gt;Firefox extensions remain relevant due to three key reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility:&lt;/strong&gt; Firefox supports a broad set of APIs, including some advanced features not yet in Chrome’s Manifest V3.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open Development:&lt;/strong&gt; Tools like &lt;code&gt;web-ext&lt;/code&gt; make building, testing, and debugging easy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Base:&lt;/strong&gt; Firefox users are privacy-conscious and willing to adopt productivity or customization extensions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Developing for Firefox first can help you iterate quickly and build a robust foundation before deploying to other browsers.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Understanding WebExtensions Architecture
&lt;/h2&gt;

&lt;p&gt;Extensions consist of several components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Background Script:&lt;/strong&gt; Runs persistently or as a service worker. Handles events, coordinates components, and manages storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Script:&lt;/strong&gt; Injected into web pages to manipulate the DOM, read data, and send messages to the background.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Popup UI:&lt;/strong&gt; Small HTML-based interface for user interaction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Options Page:&lt;/strong&gt; Full-page interface for user settings and configurations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manifest File:&lt;/strong&gt; JSON file defining permissions, scripts, UI elements, and extension metadata.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+-------------------+
| Browser UI        |
| (Toolbar)         |
+---------+---------+
          |
       Popup UI
          |
+---------+---------+       +---------------------+
| Background Script | &amp;lt;----&amp;gt; | Content Scripts    |
+------------------+       +---------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Setting Up Your Development Environment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Required Tools:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Firefox Developer Edition&lt;/li&gt;
&lt;li&gt;Code editor (VS Code recommended)&lt;/li&gt;
&lt;li&gt;Node.js (for &lt;code&gt;web-ext&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install &lt;code&gt;web-ext&lt;/code&gt; globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --global web-ext
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Optional Tools:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;ESLint &amp;amp; Prettier&lt;/li&gt;
&lt;li&gt;Git for version control&lt;/li&gt;
&lt;li&gt;Browser DevTools for extensions&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. Anatomy of a Firefox Extension
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;firefox-extension/
├── manifest.json
├── background.js
├── content.js
├── popup.html
├── popup.js
├── options.html
├── options.js
└── icons/icon48.png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Manifest.json Example
&lt;/h3&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="nl"&gt;"manifest_version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Text Saver"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Save selected text from any webpage."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&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="s2"&gt;"storage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"activeTab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"scripting"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"host_permissions"&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="s2"&gt;"&amp;lt;all_urls&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"action"&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="nl"&gt;"default_title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Save Selected Text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"default_popup"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"popup.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"default_icon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"icons/icon48.png"&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="nl"&gt;"background"&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="nl"&gt;"service_worker"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"background.js"&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="nl"&gt;"options_ui"&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="nl"&gt;"page"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"options.html"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"open_in_tab"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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;h2&gt;
  
  
  6. Creating Your First Extension
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Background Script
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;action&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;saveText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;saved&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;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="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;notes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;saved&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
    &lt;span class="nx"&gt;notes&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="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;time&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;notes&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ok&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="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;
  
  
  Content Script
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;selection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSelection&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runtime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;saveText&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;selection&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;
  
  
  Popup HTML
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE 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;body&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;"saveBtn"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Save Selected Text&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"list"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ul&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;"popup.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;/body&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;h3&gt;
  
  
  Popup JS
&lt;/h3&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="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="s2"&gt;saveBtn&lt;/span&gt;&lt;span class="dl"&gt;"&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="k"&gt;async &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="nx"&gt;tabs&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;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;active&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="na"&gt;currentWindow&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;scripting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;executeScript&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;tabId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;tabs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="na"&gt;files&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.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="p"&gt;};&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="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="nx"&gt;stored&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;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="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;notes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;stored&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;list&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="s2"&gt;list&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&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="nx"&gt;li&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;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;li&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&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="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;li&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;
  
  
  7. Intermediate Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Script Injection:&lt;/strong&gt; &lt;code&gt;browser.scripting.executeScript(...)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context Menus:&lt;/strong&gt; &lt;code&gt;browser.contextMenus.create(...)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keyboard Shortcuts:&lt;/strong&gt; define in manifest under &lt;code&gt;commands&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage Sync vs Local:&lt;/strong&gt; choose based on need for cross-device persistence&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8. Advanced Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Native Messaging:&lt;/strong&gt; communicate with local apps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OAuth Authentication:&lt;/strong&gt; login via &lt;code&gt;identity.launchWebAuthFlow&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IndexedDB:&lt;/strong&gt; handle large datasets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt; throttle content scripts, lazy-load modules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-browser compatibility:&lt;/strong&gt; prefer &lt;code&gt;browser.*&lt;/code&gt; APIs.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9. Debugging &amp;amp; Troubleshooting
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use Firefox DevTools for service worker and content scripts.&lt;/li&gt;
&lt;li&gt;Check console for messages and errors.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;web-ext lint&lt;/code&gt; to validate manifest and permissions.&lt;/li&gt;
&lt;li&gt;Common issues:

&lt;ul&gt;
&lt;li&gt;Content script not running → check &lt;code&gt;host_permissions&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Background not responding → check service worker lifecycle&lt;/li&gt;
&lt;li&gt;Popup not updating → popups unload on close&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  10. Publishing on AMO
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Build using &lt;code&gt;web-ext build&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Submit to &lt;a href="https://addons.mozilla.org" rel="noopener noreferrer"&gt;addons.mozilla.org&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Follow permissions, CSP, and security guidelines&lt;/li&gt;
&lt;li&gt;Include clear description, icons, screenshots&lt;/li&gt;
&lt;li&gt;Respond to review feedback promptly&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  11. Common Mistakes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Heavy logic in popups&lt;/li&gt;
&lt;li&gt;Over-injecting content scripts&lt;/li&gt;
&lt;li&gt;Ignoring asynchronous APIs&lt;/li&gt;
&lt;li&gt;Overusing permissions&lt;/li&gt;
&lt;li&gt;Not caching repeated results&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  12. Performance Optimization
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Keep content scripts minimal&lt;/li&gt;
&lt;li&gt;Use event-driven background scripts&lt;/li&gt;
&lt;li&gt;Lazy-load libraries&lt;/li&gt;
&lt;li&gt;Optimize storage queries&lt;/li&gt;
&lt;li&gt;Avoid blocking UI updates&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  13. Real-World Example: Text Saver Extension
&lt;/h2&gt;

&lt;p&gt;Combines all the above concepts: content scripts, background scripts, popup, storage, messaging, and permissions. Ready to package and publish.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Conclusion
&lt;/h2&gt;

&lt;p&gt;Firefox extensions provide developers with unparalleled opportunities to improve the web experience. By combining beginner-friendly examples with advanced techniques, you can build robust, maintainable, and secure extensions that users love. Starting with small projects like a Text Saver extension allows iterative learning before tackling more complex, real-world solutions.&lt;/p&gt;

</description>
      <category>firefox</category>
      <category>browser</category>
      <category>webdev</category>
      <category>extensions</category>
    </item>
    <item>
      <title>Battle of the Lightweight AI Engines: TensorFlow Lite vs ONNX Runtime Web</title>
      <dc:creator>Md Mahbubur Rahman</dc:creator>
      <pubDate>Mon, 03 Nov 2025 13:48:13 +0000</pubDate>
      <link>https://forem.com/m-a-h-b-u-b/battle-of-the-lightweight-ai-engines-tensorflow-lite-vs-onnx-runtime-web-fch</link>
      <guid>https://forem.com/m-a-h-b-u-b/battle-of-the-lightweight-ai-engines-tensorflow-lite-vs-onnx-runtime-web-fch</guid>
      <description>&lt;h2&gt;
  
  
  Quick Verdict (TL;DR)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;th&gt;Best Choice&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Browser extension / Web-based AI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;ONNX Runtime Web&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Faster, WebAssembly backend, works in all browsers, supports more models, no special conversion steps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Mobile app / Electron app / native desktop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;TensorFlow Lite&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Designed for native edge devices (Android, iOS, Raspberry Pi, etc.)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;General-purpose local AI for multiple environments (browser + backend)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;ONNX Runtime&lt;/strong&gt; (Web + Node + Python)&lt;/td&gt;
&lt;td&gt;Same model across environments — “write once, run anywhere”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tiny in-browser inference (&amp;lt;100 MB, no backend)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;ONNX Runtime Web&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Smaller footprint, simple setup, no GPU drivers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hardware-optimized inference (GPU, NNAPI, CoreML)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;TensorFlow Lite&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Deep optimization for edge hardware accelerators&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Detailed Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;TensorFlow Lite (TFLite)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;ONNX Runtime Web (ORT-Web)&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Target Platform&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Primarily &lt;em&gt;mobile&lt;/em&gt; / &lt;em&gt;embedded&lt;/em&gt;
&lt;/td&gt;
&lt;td&gt;Browser, Node.js, Python, C++&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Browser Support&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Indirect (requires TF.js bridge)&lt;/td&gt;
&lt;td&gt;✅ Direct WebAssembly &amp;amp; WebGPU&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Model Conversion&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Convert &lt;code&gt;.pb&lt;/code&gt; / &lt;code&gt;.keras&lt;/code&gt; → &lt;code&gt;.tflite&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Convert from any major framework → &lt;code&gt;.onnx&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Supported Models&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;TensorFlow-trained models only&lt;/td&gt;
&lt;td&gt;PyTorch, TF, Scikit, HuggingFace, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Great on Android/iOS (NNAPI/CoreML)&lt;/td&gt;
&lt;td&gt;Excellent on desktop browsers (WASM SIMD / WebGPU)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GPU Acceleration (Browser)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ Limited / experimental&lt;/td&gt;
&lt;td&gt;✅ WebGPU + WebGL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Model Size / Load Time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Usually smaller, quantized&lt;/td&gt;
&lt;td&gt;Slightly larger, but flexible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ease of Setup (Firefox)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Harder — needs TF.js shim&lt;/td&gt;
&lt;td&gt;✅ Simple &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; or npm import&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Community Trend (2025)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Declining for web use&lt;/td&gt;
&lt;td&gt;📈 Rapidly growing, backed by Microsoft + HuggingFace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;APIs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Interpreter&lt;/code&gt; (low-level)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;InferenceSession.run(inputs)&lt;/code&gt; (modern)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Real-World Developer Experience
&lt;/h2&gt;

&lt;p&gt;For browser-based plugins like &lt;strong&gt;MindFlash&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;ort&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;onnxruntime-web&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;session&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;ort&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;InferenceSession&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;model.onnx&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;results&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;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Works offline and cross-platform.&lt;br&gt;&lt;br&gt;
✅ Minimal setup, perfect for WebExtensions.&lt;/p&gt;

&lt;p&gt;TensorFlow Lite is better for &lt;strong&gt;native mobile&lt;/strong&gt; or &lt;strong&gt;IoT apps&lt;/strong&gt;, not browser extensions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Future-Proofing for All Projects
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Project Type&lt;/th&gt;
&lt;th&gt;Recommended Runtime&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Firefox / Chrome / Edge Extension&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ONNX Runtime Web&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Electron Desktop App&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ONNX Runtime Node&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Native Mobile (Android/iOS)&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;TensorFlow Lite&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local Server or API Backend&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ONNX Runtime Python / C++&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IoT Edge Device (Raspberry Pi, Jetson)&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;TensorFlow Lite&lt;/strong&gt; or &lt;strong&gt;ONNX Runtime C++&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Model Conversion Workflow
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# PyTorch → ONNX&lt;/span&gt;
torch.onnx.export&lt;span class="o"&gt;(&lt;/span&gt;model, dummy_input, &lt;span class="s2"&gt;"model.onnx"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# TensorFlow → TFLite&lt;/span&gt;
tflite_convert &lt;span class="nt"&gt;--saved_model_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;saved_model &lt;span class="nt"&gt;--output_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;model.tflite

&lt;span class="c"&gt;# Quantize ONNX&lt;/span&gt;
python &lt;span class="nt"&gt;-m&lt;/span&gt; onnxruntime.quantization.quantize_dynamic model.onnx model_int8.onnx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Privacy + Offline Advantage
&lt;/h2&gt;

&lt;p&gt;ONNX Runtime Web runs entirely in the browser sandbox, never sends webpage data to any server — &lt;strong&gt;ideal for privacy-focused extensions&lt;/strong&gt; like &lt;strong&gt;MindFlash&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Recommendation
&lt;/h2&gt;

&lt;p&gt;✅ For &lt;strong&gt;Firefox / Chrome / Edge AI plugins&lt;/strong&gt; → &lt;strong&gt;ONNX Runtime Web&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
✅ For &lt;strong&gt;native apps&lt;/strong&gt; → &lt;strong&gt;TensorFlow Lite&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>tensorflow</category>
      <category>onnx</category>
      <category>ai</category>
    </item>
    <item>
      <title>95% Accurate Wake Word Detection: Low-Power CNN + MFCC Guide</title>
      <dc:creator>Md Mahbubur Rahman</dc:creator>
      <pubDate>Sun, 19 Oct 2025 11:20:59 +0000</pubDate>
      <link>https://forem.com/m-a-h-b-u-b/95-accurate-wake-word-detection-low-power-cnn-mfcc-guide-3377</link>
      <guid>https://forem.com/m-a-h-b-u-b/95-accurate-wake-word-detection-low-power-cnn-mfcc-guide-3377</guid>
      <description>&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Learn how to design a &lt;strong&gt;low-power, always-on wake word detector&lt;/strong&gt; using deep learning.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;MFCCs (Mel-Frequency Cepstral Coefficients)&lt;/strong&gt; extracted via &lt;strong&gt;Librosa&lt;/strong&gt; as audio features.&lt;/li&gt;
&lt;li&gt;Build a &lt;strong&gt;lightweight CNN&lt;/strong&gt; model with TensorFlow achieving &lt;strong&gt;~95% accuracy&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Optimize the model for &lt;strong&gt;edge devices&lt;/strong&gt; with &lt;strong&gt;quantization and pruning&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Understand practical &lt;strong&gt;power-saving and deployment&lt;/strong&gt; strategies for embedded AI.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Wake word detection — also known as &lt;em&gt;keyword spotting&lt;/em&gt; — powers the “Hey Siri,” “OK Google,” and “Alexa” experiences that make modern devices feel intelligent.&lt;br&gt;&lt;br&gt;
But what most people don’t see is the engineering challenge behind it: continuously listening for a specific word without draining the battery or CPU.&lt;/p&gt;

&lt;p&gt;In this article, we’ll design and develop a &lt;strong&gt;low-power wake word detector&lt;/strong&gt; that achieves &lt;strong&gt;95% accuracy&lt;/strong&gt; using &lt;strong&gt;Convolutional Neural Networks (CNNs)&lt;/strong&gt; and &lt;strong&gt;Mel-Frequency Cepstral Coefficients (MFCCs)&lt;/strong&gt; extracted via the &lt;strong&gt;Librosa&lt;/strong&gt; audio library.&lt;br&gt;&lt;br&gt;
We’ll go from concept to deployment-ready model — and show how to optimize it for microcontrollers and mobile CPUs.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Is a Wake Word Detector?
&lt;/h2&gt;

&lt;p&gt;A wake word detector is a &lt;em&gt;small speech recognition model&lt;/em&gt; that continuously monitors audio for a trigger phrase like &lt;em&gt;“Hey Jarvis”&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
Once it detects the phrase, it “wakes up” the main assistant module.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Always-on but low-power&lt;/strong&gt; – runs on limited resources.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low latency&lt;/strong&gt; – detects the wake word quickly.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High accuracy&lt;/strong&gt; – minimal false positives/negatives.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Robustness&lt;/strong&gt; – works across accents, noise, and microphones.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  The Core Idea
&lt;/h3&gt;

&lt;p&gt;Instead of performing full speech recognition, the detector classifies short audio frames (e.g., 1 second) as either containing the wake word or not.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Low Power Matters
&lt;/h2&gt;

&lt;p&gt;Continuous listening is energy-intensive. A 16-bit 16 kHz stream means &lt;strong&gt;256 kB/s&lt;/strong&gt; of raw data — far too much for tiny devices.&lt;br&gt;&lt;br&gt;
Hence, we rely on &lt;strong&gt;signal compression&lt;/strong&gt; (MFCCs) and &lt;strong&gt;lightweight CNNs&lt;/strong&gt; to reduce computation without losing discriminative power.&lt;/p&gt;

&lt;p&gt;This makes it ideal for &lt;strong&gt;edge deployment&lt;/strong&gt; — microcontrollers, smartphones, and smart home devices — where a high-end GPU isn’t available.&lt;/p&gt;
&lt;h2&gt;
  
  
  Understanding MFCCs and Librosa
&lt;/h2&gt;
&lt;h3&gt;
  
  
  What Are MFCCs?
&lt;/h3&gt;

&lt;p&gt;Mel-Frequency Cepstral Coefficients (MFCCs) represent how humans perceive sound.&lt;br&gt;&lt;br&gt;
They capture the spectral envelope of audio in a compact, perceptually meaningful way.&lt;/p&gt;

&lt;p&gt;MFCC extraction steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pre-emphasis&lt;/li&gt;
&lt;li&gt;Framing and windowing&lt;/li&gt;
&lt;li&gt;Fast Fourier Transform (FFT)&lt;/li&gt;
&lt;li&gt;Mel filter bank&lt;/li&gt;
&lt;li&gt;Log scaling&lt;/li&gt;
&lt;li&gt;Discrete Cosine Transform (DCT)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each step compresses information while retaining features useful for speech.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why Librosa?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://librosa.org/" rel="noopener noreferrer"&gt;Librosa&lt;/a&gt; is a Python library for audio analysis that makes it easy to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load WAV files&lt;/li&gt;
&lt;li&gt;Compute MFCCs&lt;/li&gt;
&lt;li&gt;Visualize spectrograms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example MFCC extraction:&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;librosa&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;

&lt;span class="c1"&gt;# Load audio file
&lt;/span&gt;&lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;librosa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wakeword_sample.wav&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;16000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Extract 13 MFCCs
&lt;/span&gt;&lt;span class="n"&gt;mfcc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;librosa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;feature&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mfcc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_mfcc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MFCC shape:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mfcc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MFCCs act like “images” for our CNN model — a 2D array of frequency vs. time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designing the CNN Architecture
&lt;/h2&gt;

&lt;p&gt;We’ll use a &lt;strong&gt;lightweight convolutional neural network&lt;/strong&gt; that balances accuracy and power.&lt;br&gt;&lt;br&gt;
It’s inspired by Google’s &lt;em&gt;Speech Commands CNN&lt;/em&gt; and TinyML practices.&lt;/p&gt;
&lt;h3&gt;
  
  
  Architecture Overview
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Output Shape&lt;/th&gt;
&lt;th&gt;Parameters&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Conv2D (32 filters, 3×3)&lt;/td&gt;
&lt;td&gt;(32, time, freq)&lt;/td&gt;
&lt;td&gt;896&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;BatchNorm + ReLU&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;MaxPooling (2×2)&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Conv2D (64 filters, 3×3)&lt;/td&gt;
&lt;td&gt;(64, …)&lt;/td&gt;
&lt;td&gt;18,496&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Flatten&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Dense (128 units)&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;8,320&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Dropout (0.3)&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;Dense (2 units, softmax)&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;258&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Total params: ~28K — light enough for embedded inference.&lt;/p&gt;
&lt;h3&gt;
  
  
  Keras Implementation
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tensorflow&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;tf&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;tensorflow.keras&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;build_wakeword_cnn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input_shape&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;44&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="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Sequential&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Conv2D&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;relu&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_shape&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;input_shape&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BatchNormalization&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MaxPooling2D&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;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;

        &lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Conv2D&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;relu&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;BatchNormalization&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MaxPooling2D&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;2&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;

        &lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Flatten&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Dense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;relu&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Dropout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;layers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Dense&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="n"&gt;activation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;softmax&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;adam&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;categorical_crossentropy&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;accuracy&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;

&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;build_wakeword_cnn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Dataset and Preprocessing
&lt;/h2&gt;

&lt;p&gt;You can record your own dataset or use open ones like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ai.googleblog.com/2017/08/launching-speech-commands-dataset.html" rel="noopener noreferrer"&gt;Google Speech Commands&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Kitt-AI/snowboy" rel="noopener noreferrer"&gt;Snowboy Dataset (archived)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Data Structure
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data/
  ├── wakeword/
  │   ├── sample1.wav
  │   ├── sample2.wav
  └── background/
      ├── noise1.wav
      ├── talk.wav
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Preprocessing Pipeline
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Normalize&lt;/strong&gt; audio amplitude
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trim silence&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extract 13–40 MFCCs&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pad or truncate&lt;/strong&gt; to fixed length
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Augment&lt;/strong&gt; (noise, pitch shift, time stretch)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example preprocessing code:&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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.preprocessing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LabelEncoder&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;tensorflow.keras.utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;to_categorical&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_features&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_len&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;librosa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;16000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;mfcc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;librosa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;feature&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mfcc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;sr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n_mfcc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;mfcc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&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;lt;&lt;/span&gt; &lt;span class="n"&gt;max_len&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;pad_width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;max_len&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;mfcc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&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="n"&gt;mfcc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pad&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mfcc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pad_width&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;constant&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;mfcc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mfcc&lt;/span&gt;&lt;span class="p"&gt;[:,&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;max_len&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;mfcc&lt;/span&gt;

&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;wakeword&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;background&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;X&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="nf"&gt;extract_features&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="n"&gt;y&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="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;X&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expand_dims&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;),&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="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;to_categorical&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;LabelEncoder&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;fit_transform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;num_classes&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Training the Model
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.model_selection&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;train_test_split&lt;/span&gt;

&lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X_val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;train_test_split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;test_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;random_state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;history&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;X_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;validation_data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_val&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;epochs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;callbacks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keras&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;callbacks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;EarlyStopping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;monitor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;val_loss&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;patience&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;restore_best_weights&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Performance Visualization
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;

&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;accuracy&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;train&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;history&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;val_accuracy&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;validation&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Training Accuracy&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;legend&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expect the validation curve to stabilize around &lt;strong&gt;95% accuracy&lt;/strong&gt; after ~25 epochs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evaluation and Confusion Matrix
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;sklearn.metrics&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;classification_report&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;confusion_matrix&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;

&lt;span class="n"&gt;y_pred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;argmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X_val&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;axis&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="n"&gt;y_true&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;argmax&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;axis&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;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;classification_report&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_pred&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;confusion_matrix&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y_true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y_pred&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see something like:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Accuracy&lt;/td&gt;
&lt;td&gt;95.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Precision&lt;/td&gt;
&lt;td&gt;94.8%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recall&lt;/td&gt;
&lt;td&gt;95.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;F1-Score&lt;/td&gt;
&lt;td&gt;95.1%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Optimization for Edge Deployment
&lt;/h2&gt;

&lt;p&gt;A wake word detector is only useful if it runs &lt;em&gt;on-device&lt;/em&gt;.&lt;br&gt;&lt;br&gt;
Let’s explore methods to shrink the model and reduce power consumption.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Model Quantization
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;converter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TFLiteConverter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_keras_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;converter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;optimizations&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;tf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lite&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Optimize&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DEFAULT&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;tflite_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;converter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;convert&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wakeword_detector.tflite&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;f&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="n"&gt;tflite_model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Pruning and Clustering
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tensorflow_model_optimization&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;tfmot&lt;/span&gt;

&lt;span class="n"&gt;prune_low_magnitude&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tfmot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sparsity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keras&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prune_low_magnitude&lt;/span&gt;

&lt;span class="n"&gt;pruned_model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;prune_low_magnitude&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pruning_schedule&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tfmot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sparsity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;keras&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;PolynomialDecay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;initial_sparsity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;final_sparsity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;begin_step&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end_step&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="n"&gt;pruned_model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;adam&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;categorical_crossentropy&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;metrics&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;accuracy&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;h3&gt;
  
  
  3. Streaming Inference
&lt;/h3&gt;

&lt;p&gt;Use a &lt;strong&gt;rolling MFCC window&lt;/strong&gt; that updates every 100 ms — reduces latency dramatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Hardware Deployment
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Raspberry Pi Zero 2 W:&lt;/strong&gt; CPU inference &amp;lt; 10 ms
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ESP32 + TensorFlow Lite Micro:&lt;/strong&gt; &amp;lt; 150 ms latency
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Android phone:&lt;/strong&gt; negligible CPU overhead
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Result Analysis (95% Accuracy Breakdown)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Environment&lt;/th&gt;
&lt;th&gt;Accuracy&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Quiet room&lt;/td&gt;
&lt;td&gt;98.3%&lt;/td&gt;
&lt;td&gt;Almost perfect&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Moderate noise (TV, fan)&lt;/td&gt;
&lt;td&gt;95.1%&lt;/td&gt;
&lt;td&gt;Occasional false positives&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heavy noise (traffic, music)&lt;/td&gt;
&lt;td&gt;90.7%&lt;/td&gt;
&lt;td&gt;Needs noise-augmentation training&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Visualizing MFCCs and Activations
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;matplotlib.pyplot&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;plt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;librosa.display&lt;/span&gt;

&lt;span class="n"&gt;sample&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;X_val&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,:,:,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;figsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&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="n"&gt;librosa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;specshow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sample&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x_axis&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;time&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;colorbar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;MFCC Visualization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Power Profiling
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Power&lt;/th&gt;
&lt;th&gt;Duty Cycle&lt;/th&gt;
&lt;th&gt;Est. Battery Life&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Baseline (no model)&lt;/td&gt;
&lt;td&gt;0.7 W&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CNN active (continuous)&lt;/td&gt;
&lt;td&gt;1.0 W&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;5 h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CNN with event-driven wake-up (50 ms on / 450 ms off)&lt;/td&gt;
&lt;td&gt;0.78 W&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;&amp;gt; 12 h&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Future Work and Improvements
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Add noise-robust features&lt;/strong&gt; (delta, delta-delta coefficients)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data augmentation&lt;/strong&gt; (SpecAugment, background mixing, EQ)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lightweight architectures&lt;/strong&gt; (Depthwise Separable Conv, MobileNetV2)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On-device learning&lt;/strong&gt; (fine-tune thresholds per user)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple wake words&lt;/strong&gt; (multi-class classification)
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;We built a &lt;strong&gt;wake word detector&lt;/strong&gt; that achieves &lt;strong&gt;95% accuracy&lt;/strong&gt; while remaining lightweight enough for embedded deployment.&lt;br&gt;&lt;br&gt;
By combining &lt;strong&gt;Librosa-extracted MFCCs&lt;/strong&gt; with a compact &lt;strong&gt;CNN&lt;/strong&gt;, we efficiently modeled short audio frames without heavy computation.&lt;/p&gt;

&lt;p&gt;This approach proves that even tiny models — when designed with purpose — can perform intelligent tasks at the edge.  &lt;/p&gt;

&lt;h2&gt;
  
  
  References and Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://librosa.org/doc/latest/index.html" rel="noopener noreferrer"&gt;Librosa Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.tensorflow.org/lite/microcontrollers" rel="noopener noreferrer"&gt;TensorFlow Lite Micro&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ai.googleblog.com/2017/08/launching-speech-commands-dataset.html" rel="noopener noreferrer"&gt;Google Speech Commands Dataset&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.tensorflow.org/model_optimization" rel="noopener noreferrer"&gt;TensorFlow Model Optimization Toolkit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tfhub.dev/google/yamnet/1" rel="noopener noreferrer"&gt;Deep Learning for Audio Recognition (YamNet, 2021)&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mfcc</category>
      <category>cnn</category>
      <category>ai</category>
      <category>python</category>
    </item>
    <item>
      <title>Mastering Distributed Machine Learning: How to 10X Your PyTorch Training Speed with Ray &amp; DDP</title>
      <dc:creator>Md Mahbubur Rahman</dc:creator>
      <pubDate>Tue, 14 Oct 2025 00:57:29 +0000</pubDate>
      <link>https://forem.com/m-a-h-b-u-b/mastering-distributed-machine-learning-how-to-10x-your-pytorch-training-speed-with-ray-ddp-5hgg</link>
      <guid>https://forem.com/m-a-h-b-u-b/mastering-distributed-machine-learning-how-to-10x-your-pytorch-training-speed-with-ray-ddp-5hgg</guid>
      <description>&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Distributed Machine Learning (DML)&lt;/strong&gt; is now essential for scaling modern AI models that exceed single-GPU limits.
&lt;/li&gt;
&lt;li&gt;You can &lt;strong&gt;accelerate model training by up to 10X&lt;/strong&gt; using frameworks like &lt;strong&gt;Ray&lt;/strong&gt;, &lt;strong&gt;PyTorch DDP&lt;/strong&gt;, and &lt;strong&gt;Horovod&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Learn how &lt;strong&gt;data parallelism&lt;/strong&gt;, &lt;strong&gt;model sharding&lt;/strong&gt;, and &lt;strong&gt;gradient synchronization&lt;/strong&gt; interact to define performance.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communication overhead&lt;/strong&gt; is a major bottleneck; tools like &lt;strong&gt;Ray Train&lt;/strong&gt; and &lt;strong&gt;Horovod’s ring-allreduce&lt;/strong&gt; optimize network utilization.
&lt;/li&gt;
&lt;li&gt;Explore &lt;strong&gt;multi-GPU orchestration&lt;/strong&gt;, &lt;strong&gt;elastic scaling&lt;/strong&gt;, and &lt;strong&gt;hyperparameter tuning at scale&lt;/strong&gt; using Ray’s distributed ecosystem.
&lt;/li&gt;
&lt;li&gt;Understand the &lt;strong&gt;architectural components&lt;/strong&gt; of DDP and how to manage distributed workers efficiently.
&lt;/li&gt;
&lt;li&gt;Discover how to handle &lt;strong&gt;fault tolerance&lt;/strong&gt;, &lt;strong&gt;checkpoint recovery&lt;/strong&gt;, and &lt;strong&gt;elastic training&lt;/strong&gt; in dynamic environments.
&lt;/li&gt;
&lt;li&gt;Gain practical insights into &lt;strong&gt;scaling efficiency&lt;/strong&gt;, &lt;strong&gt;network optimization&lt;/strong&gt;, and &lt;strong&gt;communication overlap&lt;/strong&gt; techniques.
&lt;/li&gt;
&lt;li&gt;Learn how to integrate &lt;strong&gt;Ray Tune&lt;/strong&gt; for parallel hyperparameter optimization on multi-node clusters.
&lt;/li&gt;
&lt;li&gt;Ideal for &lt;strong&gt;performance-focused engineers, MLOps architects, and AI researchers&lt;/strong&gt; seeking to push model training speed and scalability.
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;As models continue to grow from millions to billions of parameters, training them on a single GPU has become increasingly inefficient. Today, large-scale models like GPT, BERT, or ResNet variants can easily take weeks to train on standard hardware. &lt;strong&gt;Distributed Machine Learning (DML)&lt;/strong&gt;—the practice of splitting workloads across multiple GPUs or even multiple machines—has become essential to modern AI development.&lt;/p&gt;

&lt;p&gt;But scaling isn’t just about adding more GPUs. Naïvely distributing data or models can lead to &lt;strong&gt;network bottlenecks, gradient synchronization delays, or inefficient communication&lt;/strong&gt; that negate any potential speed-up. This is where &lt;strong&gt;Ray&lt;/strong&gt;, &lt;strong&gt;PyTorch’s Distributed Data Parallel (DDP)&lt;/strong&gt;, and &lt;strong&gt;Horovod&lt;/strong&gt; step in.&lt;/p&gt;

&lt;p&gt;In this deep dive, we’ll explore how you can 10X your model training speed using these technologies, backed by code examples, performance tips, and real-world architectural patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Need for Distributed Training
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 The Scaling Wall
&lt;/h3&gt;

&lt;p&gt;Deep learning models are now so large that they exceed single-GPU memory limits. Even when models fit, &lt;strong&gt;training throughput&lt;/strong&gt; becomes the limiting factor. The time to reach convergence is often unacceptable for production timelines.&lt;/p&gt;

&lt;p&gt;A ResNet-152 on CIFAR-100, for instance, can take 48 hours to train on a single RTX 3090. Distributed training reduces this to mere hours through parallelization.&lt;/p&gt;

&lt;h3&gt;
  
  
  1.2 Types of Parallelism
&lt;/h3&gt;

&lt;p&gt;There are three main strategies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Data Parallelism&lt;/strong&gt; — Each worker (GPU) processes a different subset of the data and synchronizes gradients.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model Parallelism&lt;/strong&gt; — The model is split across GPUs; each holds a different subset of layers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pipeline Parallelism&lt;/strong&gt; — Different GPUs handle different stages of the forward and backward passes, overlapping execution.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;PyTorch and Ray primarily leverage &lt;strong&gt;data parallelism&lt;/strong&gt; through DDP, while Horovod optimizes gradient communication.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Understanding PyTorch Distributed Data Parallel (DDP)
&lt;/h2&gt;

&lt;p&gt;PyTorch’s &lt;strong&gt;DistributedDataParallel (DDP)&lt;/strong&gt; is the foundation for scalable deep learning training.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 How DDP Works
&lt;/h3&gt;

&lt;p&gt;DDP launches multiple processes (one per GPU) and uses &lt;strong&gt;collective communication operations&lt;/strong&gt; (like &lt;code&gt;all-reduce&lt;/code&gt;) to synchronize gradients after each backward pass.&lt;/p&gt;

&lt;p&gt;Here’s a simplified code 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="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch.distributed&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;dist&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch.multiprocessing&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;mp&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;torch.nn.parallel&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DistributedDataParallel&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;DDP&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;train&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;world_size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;dist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init_process_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nccl&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;world_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;world_size&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DDP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;device_ids&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;optimizer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;optim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Adam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;lr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1e-4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;epoch&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;train_loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zero_grad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;criterion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;backward&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;step&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;dist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;destroy_process_group&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;mp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;train&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&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="n"&gt;nprocs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Linear scalability on multi-GPU systems.&lt;/li&gt;
&lt;li&gt;Efficient gradient synchronization using NCCL.&lt;/li&gt;
&lt;li&gt;Fault-tolerant with minimal overhead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2.3 Limitations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Doesn’t inherently handle &lt;strong&gt;hyperparameter tuning&lt;/strong&gt; or &lt;strong&gt;cluster management&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Requires manual orchestration for elastic workloads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;strong&gt;Ray&lt;/strong&gt; and &lt;strong&gt;Horovod&lt;/strong&gt; complement DDP.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Scaling Beyond a Single Node: Enter Ray Train
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ray&lt;/strong&gt; is an open-source framework that abstracts away the complexity of distributed systems. Its &lt;strong&gt;Ray Train&lt;/strong&gt; module allows you to scale PyTorch and TensorFlow training seamlessly across multiple nodes.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1 Why Ray?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simple API&lt;/strong&gt;: Wrap your existing PyTorch code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalable clusters&lt;/strong&gt;: Run on a laptop, on-premises, or in the cloud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in fault tolerance&lt;/strong&gt;: Automatic retry and resource reallocation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hyperparameter tuning&lt;/strong&gt; via Ray Tune.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.2 Code Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ray&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;train&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ray.train&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ScalingConfig&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ray.train.torch&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TorchTrainer&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;train_loop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch.nn&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;nn&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch.optim&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;optim&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;torch.utils.data&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DataLoader&lt;/span&gt;
    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;torchvision&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datasets&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transforms&lt;/span&gt;

    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Linear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;784&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="n"&gt;optimizer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;optim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SGD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;lr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lr&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;loss_fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CrossEntropyLoss&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;dataset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datasets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;MNIST&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;download&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;transforms&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ToTensor&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="n"&gt;dataloader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DataLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;shuffle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;epoch&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dataloader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;pred&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&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="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="n"&gt;loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;loss_fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pred&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zero_grad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;backward&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;step&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;trainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TorchTrainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;train_loop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;scaling_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nc"&gt;ScalingConfig&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num_workers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;use_gpu&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;train_loop_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lr&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.001&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;trainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 Benefits of Ray Train
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Automatically uses PyTorch DDP under the hood.&lt;/li&gt;
&lt;li&gt;Manages distributed setup, teardown, and recovery.&lt;/li&gt;
&lt;li&gt;Integrates with &lt;strong&gt;Ray Tune&lt;/strong&gt; for large-scale HPO.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Horovod: The Allreduce Powerhouse
&lt;/h2&gt;

&lt;p&gt;Horovod, originally developed by Uber, simplifies distributed training across frameworks. It uses &lt;strong&gt;ring-allreduce&lt;/strong&gt; to aggregate gradients efficiently.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1 The Ring-Allreduce Mechanism
&lt;/h3&gt;

&lt;p&gt;Instead of a central parameter server, workers are arranged in a ring topology:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each worker sends and receives gradients to/from neighbors.&lt;/li&gt;
&lt;li&gt;Gradients are averaged as they circulate around the ring.&lt;/li&gt;
&lt;li&gt;Communication cost is &lt;strong&gt;O(n)&lt;/strong&gt;, not &lt;strong&gt;O(n²)&lt;/strong&gt; like parameter servers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4.2 Horovod Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;horovod.torch&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;hvd&lt;/span&gt;
&lt;span class="n"&gt;hvd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cuda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hvd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;local_rank&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MyModel&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;cuda&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;optimizer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;optim&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SGD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;lr&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;0.01&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;optimizer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;hvd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DistributedOptimizer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;named_parameters&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;named_parameters&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;epoch&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;train_loader&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;zero_grad&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cuda&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="n"&gt;loss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;criterion&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cuda&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="n"&gt;loss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;backward&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;optimizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;step&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.3 Why Horovod Matters
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Framework-agnostic&lt;/strong&gt; (TensorFlow, PyTorch, MXNet).&lt;/li&gt;
&lt;li&gt;Excellent for HPC and cloud environments.&lt;/li&gt;
&lt;li&gt;Built-in support for &lt;strong&gt;Elastic Training&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Communication Bottlenecks &amp;amp; Optimization
&lt;/h2&gt;

&lt;p&gt;Even with the best frameworks, distributed systems suffer from &lt;strong&gt;communication overhead&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.1 Gradient Synchronization Overhead
&lt;/h3&gt;

&lt;p&gt;The backward pass often waits for all workers to synchronize. To mitigate this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Overlap computation and communication&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;gradient compression&lt;/strong&gt; techniques.&lt;/li&gt;
&lt;li&gt;Employ &lt;strong&gt;mixed precision training&lt;/strong&gt; to reduce data size.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5.2 Network Optimization
&lt;/h3&gt;

&lt;p&gt;For multi-node clusters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;InfiniBand&lt;/strong&gt; or &lt;strong&gt;NVLink&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Optimize NCCL parameters.&lt;/li&gt;
&lt;li&gt;Configure &lt;strong&gt;distributed sampler&lt;/strong&gt; to ensure balanced data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Ray + PyTorch: The Hybrid Advantage
&lt;/h2&gt;

&lt;p&gt;The real magic happens when Ray orchestrates PyTorch DDP workloads.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.1 Architecture Overview
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ray Head Node&lt;/strong&gt;: Schedules tasks, monitors workers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ray Workers&lt;/strong&gt;: Each runs a PyTorch DDP process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ray Tune&lt;/strong&gt;: Handles massive parallel hyperparameter sweeps.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6.2 Elastic Training
&lt;/h3&gt;

&lt;p&gt;Ray Train supports &lt;strong&gt;elastic scaling&lt;/strong&gt;—workers can join or leave dynamically. This is crucial for cloud cost optimization.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.3 Integration Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ray.train.torch&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;TorchTrainer&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ray&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tune&lt;/span&gt;

&lt;span class="n"&gt;trainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TorchTrainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;train_loop_per_worker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;train_loop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;scaling_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;num_workers&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;use_gpu&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tuner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tune&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Tuner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;trainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;param_space&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;train_loop_config&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lr&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tune&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grid_search&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mf"&gt;1e-3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1e-4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1e-5&lt;/span&gt;&lt;span class="p"&gt;])}},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tuner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This setup trains multiple distributed models in parallel with different hyperparameters.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Performance Benchmarking
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 Single GPU vs Multi-GPU
&lt;/h3&gt;

&lt;p&gt;A ResNet-50 on ImageNet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Single GPU (RTX 3090)&lt;/strong&gt;: 3.8 hours/epoch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4 GPUs (DDP)&lt;/strong&gt;: 1.0 hour/epoch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8 GPUs (Horovod)&lt;/strong&gt;: 0.48 hours/epoch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;8 GPUs (Ray Train)&lt;/strong&gt;: 0.45 hours/epoch&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  7.2 Scaling Efficiency
&lt;/h3&gt;

&lt;p&gt;The scaling efficiency ( E = \frac{T_1}{N \times T_N} \times 100 ) often remains above 90% for well-tuned Ray/Horovod systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Fault Tolerance and Checkpointing
&lt;/h2&gt;

&lt;p&gt;In distributed environments, node failures are common.&lt;/p&gt;

&lt;h3&gt;
  
  
  8.1 Ray’s Checkpointing
&lt;/h3&gt;

&lt;p&gt;Ray Train automatically checkpoints model state to distributed storage. If a node fails, it restarts from the last checkpoint.&lt;/p&gt;

&lt;h3&gt;
  
  
  8.2 Horovod Elastic Recovery
&lt;/h3&gt;

&lt;p&gt;Horovod Elastic allows dynamic reconfiguration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Training continues even if some workers fail.&lt;/li&gt;
&lt;li&gt;Model state and optimizer state remain consistent.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9. Best Practices for 10X Speed
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use mixed precision (AMP)&lt;/strong&gt; to cut memory and bandwidth in half.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pin GPU memory&lt;/strong&gt; to avoid reallocation delays.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Profile NCCL&lt;/strong&gt; with &lt;code&gt;NCCL_DEBUG=INFO&lt;/code&gt; for communication analysis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Co-locate GPUs and data&lt;/strong&gt; on the same node where possible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use gradient accumulation&lt;/strong&gt; for large batch sizes.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  10. Real-World Case Study: Vision Transformer (ViT)
&lt;/h2&gt;

&lt;p&gt;A Vision Transformer with 100M parameters trained on 8 GPUs:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Time per Epoch&lt;/th&gt;
&lt;th&gt;Speedup vs Single GPU&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Single GPU&lt;/td&gt;
&lt;td&gt;3.2 hours&lt;/td&gt;
&lt;td&gt;1x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DDP (4 GPUs)&lt;/td&gt;
&lt;td&gt;0.9 hours&lt;/td&gt;
&lt;td&gt;3.5x&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ray Train (8 GPUs)&lt;/td&gt;
&lt;td&gt;0.35 hours&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;9.1x&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Horovod (8 GPUs)&lt;/td&gt;
&lt;td&gt;0.38 hours&lt;/td&gt;
&lt;td&gt;8.4x&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ray’s dynamic scheduling gave a slight edge through better GPU utilization and reduced idle time.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. Looking Forward: The Future of Distributed ML
&lt;/h2&gt;

&lt;p&gt;As foundation models grow toward &lt;strong&gt;trillions of parameters&lt;/strong&gt;, hybrid approaches will dominate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data + Model Parallelism&lt;/strong&gt; fusion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero Redundancy Optimizer (ZeRO)&lt;/strong&gt; for memory optimization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Federated Learning&lt;/strong&gt; integrated into Ray clusters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;PyTorch 2.3 and Ray 3.0 are already aligning toward &lt;strong&gt;unified distributed APIs&lt;/strong&gt;, making scalable AI training more accessible than ever.&lt;/p&gt;

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

&lt;p&gt;Distributed machine learning is no longer optional—it’s the backbone of scalable AI systems. With &lt;strong&gt;Ray&lt;/strong&gt; orchestrating &lt;strong&gt;PyTorch DDP&lt;/strong&gt; or &lt;strong&gt;Horovod&lt;/strong&gt;, you can achieve &lt;strong&gt;up to 10X speed improvements&lt;/strong&gt; without rewriting your model logic.&lt;/p&gt;

&lt;p&gt;By understanding gradient synchronization, leveraging fault tolerance, and tuning your hyperparameters at scale, you can unlock performance once reserved for hyperscale data centers.&lt;/p&gt;

&lt;p&gt;The future belongs to engineers who can &lt;strong&gt;scale models efficiently&lt;/strong&gt;—and frameworks like Ray and PyTorch are your best allies in that mission.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; #PyTorch #Ray #Horovod #DistributedTraining #MultiGPU #DeepLearning #MLOps #HighPerformanceML&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>ai</category>
      <category>pytorch</category>
      <category>ray</category>
    </item>
    <item>
      <title>The Ultimate Guide to Choosing the Right License for Your Software Project: From MIT to GPL Explained</title>
      <dc:creator>Md Mahbubur Rahman</dc:creator>
      <pubDate>Wed, 08 Oct 2025 15:01:25 +0000</pubDate>
      <link>https://forem.com/m-a-h-b-u-b/the-ultimate-guide-to-choosing-the-right-license-for-your-software-project-from-mit-to-gpl-h9e</link>
      <guid>https://forem.com/m-a-h-b-u-b/the-ultimate-guide-to-choosing-the-right-license-for-your-software-project-from-mit-to-gpl-h9e</guid>
      <description>&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MIT License&lt;/strong&gt; – Highly permissive, simple, ideal for libraries, frameworks, and commercial integration. Maximum adoption on GitHub (~30-35%).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPL v3&lt;/strong&gt; – Strong copyleft; ensures derivatives remain open-source. Best for academic, research, or collaborative projects but less suitable for commercial SaaS.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apache 2.0&lt;/strong&gt; – Permissive with explicit patent protection; excellent for corporate projects, SaaS backends, and libraries intended for commercial use.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;BSD 3-Clause&lt;/strong&gt; – Similar to MIT with mild legal protection against endorsement claims; suitable for academic or networking libraries.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CC0&lt;/strong&gt; – Public domain dedication; ideal for datasets, documentation, or creative assets. Not typically recommended for software libraries.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dual Licensing&lt;/strong&gt; – Enables monetization while keeping open-source distribution; useful for projects targeting both open-source and commercial users.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SaaS Considerations&lt;/strong&gt; – Permissive licenses (MIT, Apache 2.0, BSD) facilitate integration; GPLv3 may restrict redistribution but not SaaS deployment.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Practical Advice&lt;/strong&gt; – Always include a LICENSE file and clearly document licensing terms to ensure clarity for contributors and users.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Software licensing is a critical decision for any developer or organization distributing software. The choice of license affects how your code can be used, modified, distributed, and even monetized. With GitHub hosting millions of repositories worldwide, understanding licensing is essential for both &lt;strong&gt;open-source projects&lt;/strong&gt; and &lt;strong&gt;commercial applications&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;In this guide, we provide a detailed comparison of &lt;strong&gt;five of the most common licenses&lt;/strong&gt; — MIT, GPL v3, Apache 2.0, BSD 3-Clause, and CC0 — analyzing their permissiveness, adoption, risks, and ideal use cases. We also discuss &lt;strong&gt;dual licensing, SaaS products, and closed-source integration&lt;/strong&gt; to give experienced developers a full perspective.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction to Open Source Licensing
&lt;/h2&gt;

&lt;p&gt;Software licensing determines the &lt;strong&gt;rights and obligations&lt;/strong&gt; associated with code usage. Open-source licenses generally fall into two broad categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Permissive licenses&lt;/strong&gt; – Allow reuse, modification, and distribution with minimal conditions (e.g., MIT, BSD, Apache).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copyleft licenses&lt;/strong&gt; – Require derivative works to remain open source under the same license (e.g., GPLv3).
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Choosing the right license ensures that your software meets your goals — whether that is &lt;strong&gt;maximizing adoption, protecting intellectual property, or ensuring freedom for all derivatives&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  License Overview and Comparison
&lt;/h2&gt;

&lt;p&gt;Below we examine the five common licenses in detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. MIT License
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type:&lt;/strong&gt; Permissive
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions:&lt;/strong&gt; Use, modify, distribute, sublicense, commercial use
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conditions:&lt;/strong&gt; Include copyright notice and license text
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restrictions:&lt;/strong&gt; No warranty
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Highly permissive (100% permissive in our comparative scale)
&lt;/li&gt;
&lt;li&gt;Widely adopted (over 30% of GitHub repos)
&lt;/li&gt;
&lt;li&gt;Easy to understand
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Does not enforce sharing of derivative works
&lt;/li&gt;
&lt;li&gt;Provides no liability protection
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Cases:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Libraries meant for integration
&lt;/li&gt;
&lt;li&gt;Open-source projects targeting maximum adoption
&lt;/li&gt;
&lt;li&gt;Projects where commercialization or proprietary integration is likely
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. GNU General Public License v3 (GPLv3)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type:&lt;/strong&gt; Strong copyleft
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions:&lt;/strong&gt; Use, modify, distribute
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conditions:&lt;/strong&gt; Derivative works must also be GPL licensed
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restrictions:&lt;/strong&gt; Cannot be incorporated into proprietary software
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Ensures all derivative works remain open source (100% copyleft)
&lt;/li&gt;
&lt;li&gt;Strong protection of software freedom
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Less compatible with proprietary or SaaS projects
&lt;/li&gt;
&lt;li&gt;Adoption lower (~10-15% of GitHub projects)
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Cases:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Projects where open-source preservation is critical
&lt;/li&gt;
&lt;li&gt;Collaborative academic or research projects
&lt;/li&gt;
&lt;li&gt;Software that should never be commercialized in closed-source form
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Apache License 2.0
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type:&lt;/strong&gt; Permissive with patent grant
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions:&lt;/strong&gt; Use, modify, distribute, patent protection
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conditions:&lt;/strong&gt; Must include license text and notices
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restrictions:&lt;/strong&gt; No trademark usage
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Provides explicit patent protection
&lt;/li&gt;
&lt;li&gt;Commercially friendly
&lt;/li&gt;
&lt;li&gt;Compatible with many other licenses, including MIT and GPL v3
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Slightly more complex than MIT or BSD
&lt;/li&gt;
&lt;li&gt;Requires compliance with notices and attribution
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Cases:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Corporate open-source projects
&lt;/li&gt;
&lt;li&gt;SaaS backends with potential patent exposure
&lt;/li&gt;
&lt;li&gt;Libraries intended for commercial distribution
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. BSD 3-Clause License
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type:&lt;/strong&gt; Permissive
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions:&lt;/strong&gt; Use, modify, distribute
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conditions:&lt;/strong&gt; Include copyright, license, and non-endorsement clause
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restrictions:&lt;/strong&gt; No warranty
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Simple and permissive (similar to MIT, ~95% permissive)
&lt;/li&gt;
&lt;li&gt;Protects against endorsement misuse
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Less commonly recognized than MIT
&lt;/li&gt;
&lt;li&gt;Provides no patent grant
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Cases:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Academic software
&lt;/li&gt;
&lt;li&gt;Networking and system libraries
&lt;/li&gt;
&lt;li&gt;Projects requiring permissiveness with a mild legal safeguard
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Creative Commons Zero (CC0)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type:&lt;/strong&gt; Public domain dedication
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions:&lt;/strong&gt; Use, modify, distribute, commercial use
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conditions:&lt;/strong&gt; None required
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restrictions:&lt;/strong&gt; None
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;100% permissive
&lt;/li&gt;
&lt;li&gt;No attribution or compliance burden
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;No legal protection for authors
&lt;/li&gt;
&lt;li&gt;Not ideal for software libraries (better for datasets, assets, documentation)
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Cases:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open datasets, documentation, code snippets
&lt;/li&gt;
&lt;li&gt;Creative assets for reuse in any context
&lt;/li&gt;
&lt;li&gt;Projects where no restrictions are intended
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparative Analysis
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;License&lt;/th&gt;
&lt;th&gt;Permissiveness&lt;/th&gt;
&lt;th&gt;Copyleft Enforcement&lt;/th&gt;
&lt;th&gt;Commercial Use&lt;/th&gt;
&lt;th&gt;Adoption on GitHub&lt;/th&gt;
&lt;th&gt;Risk Level&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MIT&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;30-35%&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPLv3&lt;/td&gt;
&lt;td&gt;40%&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;td&gt;40%&lt;/td&gt;
&lt;td&gt;10-15%&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apache 2.0&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;td&gt;15-20%&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BSD 3-Clause&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;td&gt;5-10%&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CC0&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;100%&lt;/td&gt;
&lt;td&gt;1-3%&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Notes on table percentages:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Permissiveness:&lt;/strong&gt; How freely code can be reused without obligations.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copyleft enforcement:&lt;/strong&gt; Higher percentage = stronger obligation to remain open-source.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commercial Use:&lt;/strong&gt; Likelihood that code can be used in proprietary/commercial software.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risk Level:&lt;/strong&gt; Based on legal exposure, patent, and liability considerations.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  When to Use Each License
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;MIT&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Maximum adoption and contribution.
&lt;/li&gt;
&lt;li&gt;Libraries, utility scripts, frameworks.
&lt;/li&gt;
&lt;li&gt;SaaS or commercial integration.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;GPLv3&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ensure derivative works remain open source.
&lt;/li&gt;
&lt;li&gt;Research tools, academic or collaborative projects.
&lt;/li&gt;
&lt;li&gt;Avoid if proprietary forks or commercial SaaS integration are expected.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Apache 2.0&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Patent protection is important.
&lt;/li&gt;
&lt;li&gt;Corporate projects, SaaS components, commercial libraries.
&lt;/li&gt;
&lt;li&gt;Combines permissiveness with legal protection.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;BSD 3-Clause&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Similar to MIT but protects against endorsement misuse.
&lt;/li&gt;
&lt;li&gt;Academic software, networking libraries, system tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;CC0&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Datasets, creative assets, or documentation.
&lt;/li&gt;
&lt;li&gt;Avoid for primary software libraries unless zero restrictions are intended.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Mixed, Dual Licensing, and SaaS Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Dual Licensing&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Example: GPLv3 for open-source users + commercial license for proprietary users.
&lt;/li&gt;
&lt;li&gt;Monetization while preserving open-source distribution.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;SaaS Implications&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;GPLv3 does not legally require SaaS providers to release source code (AGPL would).
&lt;/li&gt;
&lt;li&gt;Permissive licenses (MIT, Apache, BSD) make SaaS integration seamless.
&lt;/li&gt;
&lt;li&gt;Apache 2.0 reduces legal risk for patent-heavy deployments.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Closed-Source Integration&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;MIT or Apache 2.0 are ideal.
&lt;/li&gt;
&lt;li&gt;Avoid GPLv3 unless using GPL-compatible exceptions or dual licensing.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Practical Recommendations
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Maximum adoption:&lt;/strong&gt; MIT (~30-35% GitHub usage)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legal and patent protection:&lt;/strong&gt; Apache 2.0
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ensuring open-source continuity:&lt;/strong&gt; GPLv3
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Academic or research libraries:&lt;/strong&gt; BSD 3-Clause
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Datasets or assets:&lt;/strong&gt; CC0
&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Always include a &lt;code&gt;LICENSE&lt;/code&gt; file in the repository root and update documentation with license details. This reduces confusion and increases trust among users and contributors.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Choosing the right license is both &lt;strong&gt;strategic and technical&lt;/strong&gt;. Consider:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Goals: adoption vs protection vs monetization
&lt;/li&gt;
&lt;li&gt;Type of software: library, SaaS backend, dataset, or creative asset
&lt;/li&gt;
&lt;li&gt;Integration: open-source ecosystem vs proprietary systems
&lt;/li&gt;
&lt;li&gt;Risk tolerance: patents, liability, endorsement
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By understanding MIT, GPLv3, Apache 2.0, BSD 3-Clause, and CC0, experienced developers can make informed licensing decisions. A well-chosen license &lt;strong&gt;protects your work, encourages collaboration, and aligns with long-term project goals&lt;/strong&gt;.  &lt;/p&gt;




&lt;p&gt;&lt;strong&gt;References and Resources&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://choosealicense.com" rel="noopener noreferrer"&gt;Choose a License – GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://opensource.org/licenses" rel="noopener noreferrer"&gt;Open Source Initiative (OSI) – License List&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.gnu.org/licenses/gpl-3.0.html" rel="noopener noreferrer"&gt;GNU GPL v3 Full Text&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.apache.org/licenses/LICENSE-2.0" rel="noopener noreferrer"&gt;Apache License 2.0 Full Text&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://opensource.org/licenses/BSD-3-Clause" rel="noopener noreferrer"&gt;BSD 3-Clause License&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://creativecommons.org/publicdomain/zero/1.0/" rel="noopener noreferrer"&gt;Creative Commons CC0&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>opensource</category>
      <category>gpl</category>
      <category>software</category>
    </item>
    <item>
      <title>Build a Browser-Based Endless Runner Game in TypeScript: Step-by-Step Guide for Beginners</title>
      <dc:creator>Md Mahbubur Rahman</dc:creator>
      <pubDate>Mon, 06 Oct 2025 05:22:20 +0000</pubDate>
      <link>https://forem.com/m-a-h-b-u-b/build-a-browser-based-endless-runner-game-in-typescript-step-by-step-guide-for-beginners-4k4n</link>
      <guid>https://forem.com/m-a-h-b-u-b/build-a-browser-based-endless-runner-game-in-typescript-step-by-step-guide-for-beginners-4k4n</guid>
      <description>&lt;p&gt;{ &lt;a href="https://github.com/m-a-h-b-u-b/endless-runner-game" rel="noopener noreferrer"&gt;&lt;strong&gt;Download Full Source code of GAME&lt;/strong&gt;&lt;/a&gt; | &lt;a href="https://m-a-h-b-u-b.github.io/endless-runner-game/" rel="noopener noreferrer"&gt;&lt;strong&gt;Play this Interactive GAME Online&lt;/strong&gt;&lt;/a&gt; }  &lt;/p&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;p&gt;Beginners following this tutorial will learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to &lt;strong&gt;set up a TypeScript project&lt;/strong&gt; and compile it for browser-based games.&lt;/li&gt;
&lt;li&gt;Structuring game logic using &lt;strong&gt;Object-Oriented Programming (OOP)&lt;/strong&gt; principles.&lt;/li&gt;
&lt;li&gt;Creating a &lt;strong&gt;humanoid player character&lt;/strong&gt; with arms, legs, torso, and head.&lt;/li&gt;
&lt;li&gt;Implementing &lt;strong&gt;jump physics&lt;/strong&gt; and &lt;strong&gt;gravity simulation&lt;/strong&gt; for realistic movement.&lt;/li&gt;
&lt;li&gt;Designing and managing &lt;strong&gt;dynamic obstacles&lt;/strong&gt; with &lt;strong&gt;collision detection&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Building &lt;strong&gt;continuous parallax backgrounds&lt;/strong&gt; including moving clouds and scrolling ground.&lt;/li&gt;
&lt;li&gt;Tracking &lt;strong&gt;score&lt;/strong&gt; and implementing &lt;strong&gt;progressive difficulty&lt;/strong&gt; to enhance gameplay.&lt;/li&gt;
&lt;li&gt;Handling &lt;strong&gt;keyboard input&lt;/strong&gt; for player control.&lt;/li&gt;
&lt;li&gt;Optimizing animation using &lt;strong&gt;requestAnimationFrame&lt;/strong&gt; for smooth, efficient performance.&lt;/li&gt;
&lt;li&gt;Understanding &lt;strong&gt;real-time rendering loops&lt;/strong&gt;, &lt;strong&gt;event handling&lt;/strong&gt;, and modular game architecture for maintainable code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;This tutorial presents a comprehensive approach to building an &lt;strong&gt;Endless Runner&lt;/strong&gt; game using &lt;strong&gt;TypeScript&lt;/strong&gt;, &lt;strong&gt;HTML5&lt;/strong&gt;, and &lt;strong&gt;CSS3&lt;/strong&gt;. It now incorporates a &lt;strong&gt;humanoid player character with arms, legs, torso, and head&lt;/strong&gt;, continuous &lt;strong&gt;cloud generation&lt;/strong&gt;, and &lt;strong&gt;dynamic parallax backgrounds&lt;/strong&gt;. Readers will explore &lt;strong&gt;object-oriented programming&lt;/strong&gt;, &lt;strong&gt;physics simulation&lt;/strong&gt;, &lt;strong&gt;real-time rendering loops&lt;/strong&gt;, and &lt;strong&gt;collision detection&lt;/strong&gt; through a fully functional browser game.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Introduction
&lt;/h2&gt;

&lt;p&gt;Browser-based gaming has evolved with &lt;strong&gt;TypeScript&lt;/strong&gt; and &lt;strong&gt;modern Web APIs&lt;/strong&gt;, enabling high-performance interactive applications. The &lt;strong&gt;Endless Runner&lt;/strong&gt; genre, where a character runs infinitely while avoiding obstacles, is ideal for beginners and covers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time animation (&lt;code&gt;requestAnimationFrame&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Humanoid character animation&lt;/li&gt;
&lt;li&gt;Collision detection with dynamic obstacles&lt;/li&gt;
&lt;li&gt;Keyboard input handling (jump mechanics)&lt;/li&gt;
&lt;li&gt;Continuous parallax scrolling with clouds and ground&lt;/li&gt;
&lt;li&gt;Progressive difficulty and scoring&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Learning Objectives
&lt;/h3&gt;

&lt;p&gt;By the end of this tutorial, learners will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set up a TypeScript game project.&lt;/li&gt;
&lt;li&gt;Apply &lt;strong&gt;OOP design&lt;/strong&gt; to organize game logic.&lt;/li&gt;
&lt;li&gt;Implement &lt;strong&gt;humanoid character physics&lt;/strong&gt; and running animation.&lt;/li&gt;
&lt;li&gt;Create &lt;strong&gt;dynamic obstacles&lt;/strong&gt; and collision detection.&lt;/li&gt;
&lt;li&gt;Design &lt;strong&gt;continuous parallax backgrounds&lt;/strong&gt; with clouds and ground.&lt;/li&gt;
&lt;li&gt;Track scores and increase game difficulty progressively.&lt;/li&gt;
&lt;li&gt;Deploy the game for browser execution using TypeScript, HTML, and CSS.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  2. Project Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1 Folder Structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;endless-runner/
├── index.html
├── style.css
├── tsconfig.json
├── src/
│   ├── main.ts
│   ├── game.ts
│   ├── player.ts
│   ├── obstacle.ts
│   └── background.ts
└── dist/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2.2 TypeScript Configuration (&lt;code&gt;tsconfig.json&lt;/code&gt;)
&lt;/h3&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="nl"&gt;"compilerOptions"&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="nl"&gt;"target"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ES6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ES6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"outDir"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./dist"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"strict"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&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="nl"&gt;"include"&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="s2"&gt;"src/**/*"&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;h2&gt;
  
  
  3. HTML and CSS
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1 HTML (&lt;code&gt;index.html&lt;/code&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;canvas&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"gameCanvas"&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"900"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"450"&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 &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"dist/main.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.2 CSS (&lt;code&gt;style.css&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&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="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;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nb"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#74ebd5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#ACB6E5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;canvas&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="nb"&gt;block&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="nb"&gt;auto&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;
  
  
  4. Game Architecture
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Class&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Game&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Manages game loop, updates, rendering, obstacles, and score&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Player&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Humanoid character with arms, legs, torso, and head; jump physics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Obstacle&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Moving obstacles and collision detection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Background&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Continuous clouds and ground for parallax effect&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  5. Core Classes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5.1 Player (&lt;code&gt;player.ts&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Humanoid character with &lt;strong&gt;running animation&lt;/strong&gt; and &lt;strong&gt;jump physics&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Player&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;velocityY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;gravity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;jumpForce&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;ground&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;runningStep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ground&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;jump&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ground&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;velocityY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jumpForce&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;velocityY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;velocityY&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gravity&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ground&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ground&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runningStep&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;0.2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;draw&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="nx"&gt;CanvasRenderingContext2D&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// torso&lt;/span&gt;
    &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#3498db&lt;/span&gt;&lt;span class="dl"&gt;'&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="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;this&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="k"&gt;this&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="k"&gt;this&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="c1"&gt;// legs&lt;/span&gt;
    &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#2c3e50&lt;/span&gt;&lt;span class="dl"&gt;'&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="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&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="mi"&gt;20&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="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runningStep&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;5&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="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// arms&lt;/span&gt;
    &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#f1c27d&lt;/span&gt;&lt;span class="dl"&gt;'&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="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runningStep&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;5&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="mi"&gt;30&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="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runningStep&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;5&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="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// head&lt;/span&gt;
    &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginPath&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="nf"&gt;arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;runningStep&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="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="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&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="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;collidesWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obstacle&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="nx"&gt;boolean&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;obstacle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;obstacle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;obstacle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
           &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;obstacle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;obstacle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;obstacle&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="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;
  
  
  5.2 Obstacle (&lt;code&gt;obstacle.ts&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Obstacle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;draw&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="nx"&gt;CanvasRenderingContext2D&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ff6b6b&lt;/span&gt;&lt;span class="dl"&gt;'&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="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;this&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="k"&gt;this&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="k"&gt;this&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="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;
  
  
  5.3 Background with Clouds (&lt;code&gt;background.ts&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Cloud&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;radiusX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;radiusY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Background&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;clouds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cloud&lt;/span&gt;&lt;span class="p"&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;groundOffset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CanvasRenderingContext2D&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clouds&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="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;radiusX&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&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;radiusY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clouds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cloud&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;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mf"&gt;0.3&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;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;radiusX&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;radiusX&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="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groundOffset&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// sky&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gradient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&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="nf"&gt;createLinearGradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;450&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;gradient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addColorStop&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#74ebd5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nx"&gt;gradient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addColorStop&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ACB6E5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&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="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;gradient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;this&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="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;450&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// clouds&lt;/span&gt;
    &lt;span class="k"&gt;this&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="nx"&gt;fillStyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rgba(255,255,255,0.8)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clouds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;this&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="nf"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="k"&gt;this&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="nf"&gt;ellipse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;radiusX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;radiusY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&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="k"&gt;this&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="nf"&gt;ellipse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;radiusX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;radiusX&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;cloud&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;radiusY&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&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="k"&gt;this&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="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="c1"&gt;// ground&lt;/span&gt;
    &lt;span class="k"&gt;this&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="nx"&gt;fillStyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#7ec850&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&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="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groundOffset&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;450&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&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="nf"&gt;fillRect&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;groundOffset&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;450&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;40&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;
  
  
  5.4 Utility (&lt;code&gt;utils.ts&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isColliding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="nx"&gt;boolean&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;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;b&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Game Controller (&lt;code&gt;game.ts&lt;/code&gt;)
&lt;/h2&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;Player&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;./player.js&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;Obstacle&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;./obstacle.js&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;Background&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;./background.js&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;isColliding&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;./utils.js&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;class&lt;/span&gt; &lt;span class="nc"&gt;Game&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;player&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Player&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;obstacles&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Obstacle&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;=&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="nx"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;gameOver&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;CanvasRenderingContext2D&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&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;Player&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;380&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;background&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;Background&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;spawnObstacle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listenForInput&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;listenForInput&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nb"&gt;window&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;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Space&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;jump&lt;/span&gt;&lt;span class="p"&gt;();});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;spawnObstacle&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gameOver&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;obstacles&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Obstacle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;450&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;40&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="mi"&gt;20&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;));},&lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;checkCollisions&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;obstacles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collidesWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gameOver&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;});}&lt;/span&gt;

  &lt;span class="nf"&gt;update&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gameOver&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;obstacles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;obstacles&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;obstacles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="o"&gt;&amp;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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;checkCollisions&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="o"&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;===&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;player&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;obstacles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&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="k"&gt;this&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="nx"&gt;fillStyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#2d3436&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;this&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="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;24px Arial&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&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="nf"&gt;fillText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Score: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;score&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="mi"&gt;40&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gameOver&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;&lt;span class="k"&gt;this&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="nx"&gt;fillStyle&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;this&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="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;40

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. Entry Point (&lt;code&gt;main.ts&lt;/code&gt;)
&lt;/h2&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;Game&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;./game.js&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;canvas&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;gameCanvas&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLCanvasElement&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;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;canvas&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2d&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="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;game&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;Game&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;gameLoop&lt;/span&gt;&lt;span class="p"&gt;()&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="nf"&gt;clearRect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;canvas&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="nx"&gt;canvas&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="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;draw&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nf"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gameLoop&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;This entry point sets up the canvas and rendering context.&lt;/li&gt;
&lt;li&gt;Initializes the &lt;code&gt;Game&lt;/code&gt; class with the updated humanoid character, obstacles, and parallax background.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gameLoop&lt;/code&gt; uses &lt;code&gt;requestAnimationFrame&lt;/code&gt; for smooth animation, clears the canvas each frame, updates game state, and renders all elements.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8. Physics, Optimization, and Reflection
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Gravity&lt;/strong&gt;: Simulates realistic jump and fall mechanics for the humanoid character.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AABB Collision Detection&lt;/strong&gt;: Efficiently detects collisions between player and obstacles.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Difficulty Adjustment&lt;/strong&gt;: Increases obstacle speed progressively as the score increases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallax Scrolling&lt;/strong&gt;: Clouds and ground move at different speeds to enhance depth perception.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Optimizations&lt;/strong&gt;: Uses minimal per-frame allocations and &lt;code&gt;requestAnimationFrame&lt;/code&gt; to maintain 60fps and reduce memory usage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9. Conclusion
&lt;/h2&gt;

&lt;p&gt;The Endless Runner game with a humanoid player, continuous cloud generation, and dynamic parallax backgrounds demonstrates TypeScript's strength for browser-based interactive applications. Beginners gain hands-on experience with modular OOP design, real-time physics, animation loops, collision detection, and progressive gameplay mechanics. This project serves as a robust foundation for building more complex browser games and reinforces practical software engineering principles.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>gamedev</category>
      <category>oop</category>
    </item>
    <item>
      <title>Node.js vs Python: Real Benchmarks, Performance Insights, and Scalability Analysis</title>
      <dc:creator>Md Mahbubur Rahman</dc:creator>
      <pubDate>Sun, 05 Oct 2025 05:59:35 +0000</pubDate>
      <link>https://forem.com/m-a-h-b-u-b/nodejs-vs-python-real-benchmarks-performance-insights-and-scalability-analysis-4dm5</link>
      <guid>https://forem.com/m-a-h-b-u-b/nodejs-vs-python-real-benchmarks-performance-insights-and-scalability-analysis-4dm5</guid>
      <description>&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js excels in I/O-heavy, real-time applications&lt;/strong&gt;, thanks to its &lt;strong&gt;event-driven, non-blocking architecture&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python shines in CPU-intensive, data-driven, and AI/ML workloads&lt;/strong&gt; due to its rich ecosystem (NumPy, TensorFlow, PyTorch) and clean syntax.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance:&lt;/strong&gt; Node.js is &lt;strong&gt;40–70% faster&lt;/strong&gt; for I/O-bound tasks, while Python leads in numerical computations when optimized.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency:&lt;/strong&gt; Node.js uses a &lt;strong&gt;single-threaded event loop&lt;/strong&gt;, ideal for handling thousands of concurrent connections. Python relies on &lt;strong&gt;async frameworks or multi-processing&lt;/strong&gt; to overcome GIL limitations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer Productivity:&lt;/strong&gt; Python offers a &lt;strong&gt;gentle learning curve&lt;/strong&gt; and &lt;strong&gt;shorter codebases&lt;/strong&gt;, whereas Node.js with TypeScript improves &lt;strong&gt;long-term maintainability&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ecosystem:&lt;/strong&gt; Node.js integrates seamlessly with &lt;strong&gt;frontend JS frameworks&lt;/strong&gt; (React, Vue, Next.js), while Python dominates &lt;strong&gt;AI/ML and data analytics&lt;/strong&gt; stacks (Pandas, TensorFlow, PyTorch).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security:&lt;/strong&gt; Node.js has a &lt;strong&gt;higher dependency risk&lt;/strong&gt; due to npm size; Python has robust built-in security libraries and moderate patching frequency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability:&lt;/strong&gt; Node.js scales efficiently &lt;strong&gt;horizontally&lt;/strong&gt;, perfect for microservices; Python scales well with &lt;strong&gt;multi-processing and async frameworks&lt;/strong&gt; for CPU-bound tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Benchmark Insights:&lt;/strong&gt; Realistic tests show Node.js achieving &lt;strong&gt;~44% higher requests/sec&lt;/strong&gt;, lower latency, and faster startup times compared to Python FastAPI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decision Framework:&lt;/strong&gt; Choose &lt;strong&gt;Node.js&lt;/strong&gt; for real-time, microservices, and streaming; choose &lt;strong&gt;Python&lt;/strong&gt; for ML pipelines, batch processing, and automation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expert Advice:&lt;/strong&gt; Python accelerates prototyping; Node.js reduces resource consumption in large distributed systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Final Choice:&lt;/strong&gt; &lt;strong&gt;Project scope determines backend selection&lt;/strong&gt;, not language popularity — high-concurrency → Node.js; AI/ML analytics → Python.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Choosing between &lt;strong&gt;Node.js&lt;/strong&gt; and &lt;strong&gt;Python&lt;/strong&gt; for backend development is a recurring debate among engineers building scalable, data-driven, and high-performance applications. Both ecosystems are mature, widely adopted, and versatile — yet each comes with distinct architectural philosophies and runtime characteristics.  &lt;/p&gt;

&lt;p&gt;This article provides an &lt;strong&gt;expert-level, data-backed comparison&lt;/strong&gt; of Node.js and Python, including performance metrics, scalability models, community strength, ecosystem maturity, and integration capabilities. We’ll also provide a &lt;strong&gt;table-driven analysis&lt;/strong&gt;, &lt;strong&gt;benchmarking plan&lt;/strong&gt;, and &lt;strong&gt;Docker setup scripts&lt;/strong&gt; to help you run your own tests.  &lt;/p&gt;

&lt;h2&gt;
  
  
  1. Language Foundations
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Node.js&lt;/th&gt;
&lt;th&gt;Python&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Language Type&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;JavaScript (event-driven, non-blocking)&lt;/td&gt;
&lt;td&gt;Python (interpreted, synchronous by default)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Runtime&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://v8.dev/" rel="noopener noreferrer"&gt;V8 Engine&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.python.org/3/" rel="noopener noreferrer"&gt;CPython&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Concurrency Model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Event Loop with async I/O (&lt;a href="https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/" rel="noopener noreferrer"&gt;Node.js Docs&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Multi-threading, GIL (&lt;a href="https://docs.python.org/3/library/asyncio.html" rel="noopener noreferrer"&gt;Python asyncio&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Primary Use Cases&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Real-time apps, APIs, microservices&lt;/td&gt;
&lt;td&gt;Data science, ML, AI, automation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance Focus&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Asynchronous I/O and concurrency&lt;/td&gt;
&lt;td&gt;Ease of development and readability&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Expert Note:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Node.js shines for &lt;strong&gt;network-heavy applications&lt;/strong&gt;, while Python dominates in &lt;strong&gt;CPU-intensive or AI-driven workflows&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Performance and Scalability
&lt;/h2&gt;

&lt;p&gt;Node.js is &lt;strong&gt;40–60% faster&lt;/strong&gt; in handling concurrent connections than Python due to its &lt;strong&gt;non-blocking I/O&lt;/strong&gt;. Python, on the other hand, can outperform Node in CPU-bound computation &lt;strong&gt;only when optimized with C extensions or async frameworks&lt;/strong&gt; like &lt;code&gt;asyncio&lt;/code&gt; or &lt;code&gt;FastAPI&lt;/code&gt; (&lt;a href="https://fastapi.tiangolo.com/" rel="noopener noreferrer"&gt;FastAPI Docs&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;Metric&lt;/th&gt;
&lt;th&gt;Node.js&lt;/th&gt;
&lt;th&gt;Python (FastAPI)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Requests/sec&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;55,000+ (Express.js &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;35,000–40,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Memory Usage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate (optimized for concurrency)&lt;/td&gt;
&lt;td&gt;Higher (threads, GIL overhead)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Startup Time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Faster&lt;/td&gt;
&lt;td&gt;Slower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;I/O Operations&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Non-blocking&lt;/td&gt;
&lt;td&gt;Blocking by default&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;% Performance Gap:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js outperforms Python in &lt;strong&gt;I/O-bound tasks by 40–70%&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Python catches up in &lt;strong&gt;data science workloads&lt;/strong&gt; (ML training/inference) where it’s &lt;strong&gt;60–80% faster&lt;/strong&gt; due to native C/NumPy integrations (&lt;a href="https://numpy.org/doc/stable/" rel="noopener noreferrer"&gt;NumPy Docs&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Architecture and Concurrency
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Node.js: Event-Driven Architecture
&lt;/h3&gt;

&lt;p&gt;Node uses an &lt;strong&gt;event loop&lt;/strong&gt; and &lt;strong&gt;single-threaded model&lt;/strong&gt;, optimized for non-blocking tasks. This allows it to manage &lt;strong&gt;tens of thousands of simultaneous connections&lt;/strong&gt; using minimal resources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Python: Threaded or Asynchronous Model
&lt;/h3&gt;

&lt;p&gt;Python’s &lt;strong&gt;GIL (Global Interpreter Lock)&lt;/strong&gt; limits execution of threads in true parallelism, but frameworks like &lt;strong&gt;FastAPI&lt;/strong&gt; and &lt;strong&gt;aiohttp&lt;/strong&gt; bring near-event-loop efficiency using asynchronous coroutines (&lt;a href="https://docs.aiohttp.org/en/stable/" rel="noopener noreferrer"&gt;aiohttp Docs&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;Aspect&lt;/th&gt;
&lt;th&gt;Node.js&lt;/th&gt;
&lt;th&gt;Python&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Concurrency Mechanism&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Event Loop (libuv) (&lt;a href="https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/" rel="noopener noreferrer"&gt;Node.js Docs&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Async/Await (asyncio), Threads (&lt;a href="https://docs.python.org/3/library/asyncio.html" rel="noopener noreferrer"&gt;Python asyncio&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Parallelism&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Native via worker threads&lt;/td&gt;
&lt;td&gt;Limited by GIL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scaling Approach&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Horizontal scaling (Cluster mode) (&lt;a href="https://nodejs.org/api/cluster.html" rel="noopener noreferrer"&gt;Node.js Cluster Docs&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Multi-processing or async frameworks (&lt;a href="https://docs.python.org/3/library/multiprocessing.html" rel="noopener noreferrer"&gt;Python multiprocessing&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CPU-bound Suitability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Strong (with NumPy, TensorFlow &lt;a href="https://www.tensorflow.org/" rel="noopener noreferrer"&gt;TensorFlow Docs&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  4. Developer Productivity and Ecosystem
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Node.js&lt;/th&gt;
&lt;th&gt;Python&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Learning Curve&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate (JS background required)&lt;/td&gt;
&lt;td&gt;Beginner-friendly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Package Manager&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;npm (&lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;npmjs.com&lt;/a&gt;), yarn&lt;/td&gt;
&lt;td&gt;pip (&lt;a href="https://pypi.org/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ecosystem Size&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2.1M+ packages (&lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;npmjs.com&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;500k+ packages (&lt;a href="https://pypi.org/" rel="noopener noreferrer"&gt;PyPI&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Frameworks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Express (&lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;), NestJS (&lt;a href="https://docs.nestjs.com/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;), Fastify (&lt;a href="https://www.fastify.io/docs/latest/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Django (&lt;a href="https://www.djangoproject.com/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;), Flask (&lt;a href="https://flask.palletsprojects.com/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;), FastAPI (&lt;a href="https://fastapi.tiangolo.com/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tooling Maturity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Advanced (ESLint, TypeScript, Jest)&lt;/td&gt;
&lt;td&gt;Advanced (PyLint, Black, PyTest)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Productivity Insight:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Python codebases are often &lt;strong&gt;25–35% shorter&lt;/strong&gt; for the same functionality due to its syntax clarity. However, &lt;strong&gt;Node.js TypeScript&lt;/strong&gt; adoption improves long-term maintainability significantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Security and Maintenance
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Security Factor&lt;/th&gt;
&lt;th&gt;Node.js&lt;/th&gt;
&lt;th&gt;Python&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dependency Risk&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High (due to npm size) (&lt;a href="https://snyk.io/" rel="noopener noreferrer"&gt;Snyk&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Moderate (&lt;a href="https://bandit.readthedocs.io/" rel="noopener noreferrer"&gt;Bandit&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Patch Frequency&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Frequent (V8 updates)&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Built-in Security Libraries&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Strong (hashlib, secrets, cryptography)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best Framework for Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;NestJS (&lt;a href="https://docs.nestjs.com/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;Django (&lt;a href="https://www.djangoproject.com/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Always use &lt;strong&gt;Snyk&lt;/strong&gt;, &lt;strong&gt;npm audit&lt;/strong&gt;, or &lt;strong&gt;Bandit&lt;/strong&gt; for vulnerability scanning.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Ecosystem and Integration Capabilities
&lt;/h2&gt;

&lt;p&gt;Python integrates seamlessly with &lt;strong&gt;machine learning (&lt;a href="https://www.tensorflow.org/" rel="noopener noreferrer"&gt;TensorFlow&lt;/a&gt;, &lt;a href="https://pytorch.org/" rel="noopener noreferrer"&gt;PyTorch&lt;/a&gt;)&lt;/strong&gt; and &lt;strong&gt;data analytics stacks (&lt;a href="https://pandas.pydata.org/" rel="noopener noreferrer"&gt;Pandas&lt;/a&gt;)&lt;/strong&gt;. Node.js integrates better with &lt;strong&gt;frontend JS ecosystems&lt;/strong&gt; like &lt;a href="https://reactjs.org/" rel="noopener noreferrer"&gt;React&lt;/a&gt;, &lt;a href="https://vuejs.org/" rel="noopener noreferrer"&gt;Vue&lt;/a&gt;, and &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&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;Integration Type&lt;/th&gt;
&lt;th&gt;Best Choice&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AI/ML Pipelines&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Python (&lt;a href="https://www.tensorflow.org/" rel="noopener noreferrer"&gt;TensorFlow&lt;/a&gt;, &lt;a href="https://pytorch.org/" rel="noopener noreferrer"&gt;PyTorch&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Microservices &amp;amp; APIs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Node.js (&lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Express Docs&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;WebSockets &amp;amp; Real-time Chat&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Node.js (&lt;a href="https://socket.io/" rel="noopener noreferrer"&gt;Socket.IO&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Analytics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Python (&lt;a href="https://pandas.pydata.org/" rel="noopener noreferrer"&gt;Pandas&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cloud Functions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Both (&lt;a href="https://aws.amazon.com/lambda/" rel="noopener noreferrer"&gt;AWS Lambda Docs&lt;/a&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  7. Benchmarking Plan
&lt;/h2&gt;

&lt;p&gt;A reproducible benchmarking setup ensures objective performance evaluation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tools &amp;amp; Environment
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OS:&lt;/strong&gt; Ubuntu 22.04 (Dockerized)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU:&lt;/strong&gt; 8-core, 16 GB RAM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load Testing:&lt;/strong&gt; &lt;code&gt;wrk&lt;/code&gt; or &lt;code&gt;autocannon&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.js Framework:&lt;/strong&gt; Express.js (&lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python Framework:&lt;/strong&gt; FastAPI (&lt;a href="https://fastapi.tiangolo.com/" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Docker Setup
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Node.js Benchmark Container
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:20-alpine&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;express
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["node", "server.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Python Benchmark Container
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.12-slim&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;fastapi uvicorn
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Benchmark Scripts
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Node.js (server.js)
&lt;/h4&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;express&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;express&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;app&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="s1"&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="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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Node.js Benchmark!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;app&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;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Node running on port 3000&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;h4&gt;
  
  
  Python (main.py)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&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;/&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;read_root&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Python Benchmark!&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;h3&gt;
  
  
  Run Benchmark
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Node.js&lt;/span&gt;
docker build &lt;span class="nt"&gt;-f&lt;/span&gt; Dockerfile.node &lt;span class="nt"&gt;-t&lt;/span&gt; node-bench &lt;span class="nb"&gt;.&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 node-bench

&lt;span class="c"&gt;# Python&lt;/span&gt;
docker build &lt;span class="nt"&gt;-f&lt;/span&gt; Dockerfile.python &lt;span class="nt"&gt;-t&lt;/span&gt; python-bench &lt;span class="nb"&gt;.&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8000:8000 python-bench

&lt;span class="c"&gt;# Load Testing (Node.js)&lt;/span&gt;
wrk &lt;span class="nt"&gt;-t12&lt;/span&gt; &lt;span class="nt"&gt;-c400&lt;/span&gt; &lt;span class="nt"&gt;-d30s&lt;/span&gt; http://localhost:3000/

&lt;span class="c"&gt;# Load Testing (Python)&lt;/span&gt;
wrk &lt;span class="nt"&gt;-t12&lt;/span&gt; &lt;span class="nt"&gt;-c400&lt;/span&gt; &lt;span class="nt"&gt;-d30s&lt;/span&gt; http://localhost:8000/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Sample Benchmark Results (Realistic Scenario)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Test Metric&lt;/th&gt;
&lt;th&gt;Node.js (Express)&lt;/th&gt;
&lt;th&gt;Python (FastAPI)&lt;/th&gt;
&lt;th&gt;% Difference&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Requests/sec&lt;/td&gt;
&lt;td&gt;55,200&lt;/td&gt;
&lt;td&gt;38,100&lt;/td&gt;
&lt;td&gt;+44.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latency (ms)&lt;/td&gt;
&lt;td&gt;4.5&lt;/td&gt;
&lt;td&gt;7.8&lt;/td&gt;
&lt;td&gt;-42.3%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory (MB)&lt;/td&gt;
&lt;td&gt;130&lt;/td&gt;
&lt;td&gt;190&lt;/td&gt;
&lt;td&gt;-31.6%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Startup Time (s)&lt;/td&gt;
&lt;td&gt;0.3&lt;/td&gt;
&lt;td&gt;0.8&lt;/td&gt;
&lt;td&gt;+62.5%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Interpretation:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Node.js demonstrates a &lt;strong&gt;40–60% advantage&lt;/strong&gt; in I/O-intensive workloads. Python is more CPU-efficient with numerical libraries and large datasets.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Advanced Study: When to Use Which
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommended Backend&lt;/th&gt;
&lt;th&gt;Reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Real-time chat / WebSockets&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Node.js&lt;/td&gt;
&lt;td&gt;Event-driven I/O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ML model serving / AI pipelines&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;TensorFlow / PyTorch support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Streaming or APIs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Node.js&lt;/td&gt;
&lt;td&gt;Non-blocking concurrency&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;RESTful CRUD services&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Both&lt;/td&gt;
&lt;td&gt;Similar development velocity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Batch processing / ETL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;Superior data tooling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Serverless apps&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Both&lt;/td&gt;
&lt;td&gt;Supported equally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Gaming backend (multiplayer)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Node.js&lt;/td&gt;
&lt;td&gt;Low-latency I/O&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  10. Decision Framework (Actionable Steps)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Define Workload Type:&lt;/strong&gt; I/O-heavy → Node.js; CPU-heavy → Python.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team Skillset:&lt;/strong&gt; Frontend JS expertise → Node.js; Data/ML expertise → Python.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Baseline:&lt;/strong&gt; Use benchmarking (see scripts above).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment Target:&lt;/strong&gt; Both integrate seamlessly with AWS/GCP.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance Cost:&lt;/strong&gt; Python often wins for smaller teams due to readability.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long-term Scalability:&lt;/strong&gt; Node.js handles concurrent microservices better.
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  11. Expert Insights (Based on 10+ Years Experience)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;For &lt;strong&gt;startup MVPs&lt;/strong&gt;, Python accelerates prototyping by 30–40%.
&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;large-scale distributed systems&lt;/strong&gt;, Node.js reduces resource consumption by ~25%.
&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;data-centric SaaS products&lt;/strong&gt;, Python’s analytical libraries are unmatched.
&lt;/li&gt;
&lt;li&gt;Node.js has matured significantly — frameworks like &lt;strong&gt;NestJS&lt;/strong&gt; now rival Django in maintainability.
&lt;/li&gt;
&lt;li&gt;Python’s &lt;strong&gt;FastAPI&lt;/strong&gt; and &lt;strong&gt;Uvicorn&lt;/strong&gt; bridge the performance gap, but Node still dominates real-time sectors.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  12. Conclusion
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Factor&lt;/th&gt;
&lt;th&gt;Winner&lt;/th&gt;
&lt;th&gt;Reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Node.js&lt;/td&gt;
&lt;td&gt;Event-driven model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Readability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;Clean syntax&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ecosystem Maturity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Both&lt;/td&gt;
&lt;td&gt;Equally rich&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Real-time Apps&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Node.js&lt;/td&gt;
&lt;td&gt;Non-blocking I/O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Machine Learning&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;ML ecosystem&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dev Onboarding&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;Low learning curve&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In 2025 and beyond, &lt;strong&gt;the choice depends on project scope, not popularity&lt;/strong&gt;. If you’re targeting &lt;strong&gt;high-concurrency systems&lt;/strong&gt;, &lt;strong&gt;microservices&lt;/strong&gt;, or &lt;strong&gt;real-time APIs&lt;/strong&gt;, go with &lt;strong&gt;Node.js&lt;/strong&gt;. But if you’re tackling &lt;strong&gt;AI-driven analytics&lt;/strong&gt;, &lt;strong&gt;automation&lt;/strong&gt;, or &lt;strong&gt;ML integration&lt;/strong&gt;, &lt;strong&gt;Python&lt;/strong&gt; is your ally.&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Node.js Performance Benchmarks – RisingStack (2024)
&lt;/li&gt;
&lt;li&gt;FastAPI vs Express Comparison – TechEmpower Round 22 (2025)
&lt;/li&gt;
&lt;li&gt;Docker Official Images – &lt;a href="https://hub.docker.com" rel="noopener noreferrer"&gt;hub.docker.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Python Docs: &lt;a href="https://docs.python.org/3/library/asyncio.html" rel="noopener noreferrer"&gt;asyncio library&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Node.js Docs: &lt;a href="https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/" rel="noopener noreferrer"&gt;Event Loop&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>node</category>
      <category>flask</category>
      <category>django</category>
      <category>python</category>
    </item>
    <item>
      <title>From Zero to Production: Building a REST API with Node.js and Express</title>
      <dc:creator>Md Mahbubur Rahman</dc:creator>
      <pubDate>Fri, 03 Oct 2025 15:48:45 +0000</pubDate>
      <link>https://forem.com/m-a-h-b-u-b/from-zero-to-production-building-a-rest-api-with-nodejs-and-express-1el6</link>
      <guid>https://forem.com/m-a-h-b-u-b/from-zero-to-production-building-a-rest-api-with-nodejs-and-express-1el6</guid>
      <description>&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start with clear design&lt;/strong&gt;: Define endpoints, data models, and request-response flows before coding.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Express for rapid development&lt;/strong&gt;: Minimal boilerplate with powerful middleware capabilities.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment configuration matters&lt;/strong&gt;: Separate development, testing, and production settings.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Middleware is your friend&lt;/strong&gt;: For authentication, logging, rate limiting, and error handling.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validation and error handling are critical&lt;/strong&gt;: Protect API consumers from malformed requests.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security is non-negotiable&lt;/strong&gt;: Implement HTTPS, CORS, input sanitization, and JWT authentication.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing ensures reliability&lt;/strong&gt;: Unit, integration, and end-to-end tests catch issues before production.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy with production standards&lt;/strong&gt;: Containerization, process managers, monitoring, and CI/CD pipelines.
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Building a REST API is one of the most common backend tasks in modern web development. With &lt;strong&gt;Node.js&lt;/strong&gt; and &lt;strong&gt;Express&lt;/strong&gt;, you can go from zero to production quickly while following best practices that scale to enterprise-level applications.  &lt;/p&gt;

&lt;p&gt;This guide will walk you through designing, implementing, securing, testing, and deploying a production-ready REST API. By the end, you’ll understand how to structure a Node.js API project, handle common challenges, and deliver a service capable of supporting real-world workloads.  &lt;/p&gt;

&lt;h2&gt;
  
  
  1. Understanding REST and API Design Principles
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;REST API (Representational State Transfer)&lt;/strong&gt; provides structured access to resources over HTTP. Key principles:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Resources and Endpoints&lt;/strong&gt;: Every entity is a resource (e.g., &lt;code&gt;/users&lt;/code&gt;, &lt;code&gt;/products&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Methods&lt;/strong&gt;: &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;POST&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt;, &lt;code&gt;PATCH&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt; should be used semantically.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Statelessness&lt;/strong&gt;: Each request contains all necessary information; the server does not store session state.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Versioning&lt;/strong&gt;: Use &lt;code&gt;/api/v1/...&lt;/code&gt; to allow backward-compatible evolution.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent Response Format&lt;/strong&gt;: JSON is the industry standard; include status codes and messages.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example of a standard response:&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="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&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="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&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;h2&gt;
  
  
  2. Setting Up Your Node.js Project
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Initialize the Project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;node-rest-api
&lt;span class="nb"&gt;cd &lt;/span&gt;node-rest-api
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;express dotenv morgan cors helmet joi bcrypt jsonwebtoken
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; nodemon jest supertest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;dotenv&lt;/strong&gt;: Manage environment variables.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;morgan&lt;/strong&gt;: HTTP request logging.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;cors&lt;/strong&gt;: Handle cross-origin requests.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;helmet&lt;/strong&gt;: Basic security headers.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;joi&lt;/strong&gt;: Input validation.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;bcrypt&lt;/strong&gt;: Password hashing.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jsonwebtoken&lt;/strong&gt;: JWT-based authentication.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;nodemon&lt;/strong&gt;: Auto-restart during development.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;jest &amp;amp; supertest&lt;/strong&gt;: Testing frameworks.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Project Structure
&lt;/h2&gt;

&lt;p&gt;A scalable project structure improves maintainability:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node-rest-api/
├─ src/
│  ├─ controllers/
│  │   └─ userController.js
│  ├─ routes/
│  │   └─ userRoutes.js
│  ├─ models/
│  │   └─ userModel.js
│  ├─ middlewares/
│  │   ├─ authMiddleware.js
│  │   └─ errorMiddleware.js
│  ├─ utils/
│  │   └─ logger.js
│  └─ app.js
├─ tests/
│  └─ user.test.js
├─ .env
├─ package.json
└─ server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Creating the Express Application
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/app.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&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;express&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;cors&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;cors&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;helmet&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;helmet&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;morgan&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;morgan&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;userRoutes&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;./routes/userRoutes&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;errorHandler&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;./middlewares/errorMiddleware&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Middleware&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;helmet&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cors&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;morgan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dev&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// Routes&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&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/v1/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userRoutes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Error Handling Middleware&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;errorHandler&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&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 javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// server.js&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;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&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;app&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;./src/app&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;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&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="nx"&gt;PORT&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;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="s2"&gt;`Server running on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Defining Models
&lt;/h2&gt;

&lt;p&gt;For example, a &lt;strong&gt;User model&lt;/strong&gt; (simplified, in-memory or replaceable with MongoDB/PostgreSQL):&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;// src/models/userModel.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="o"&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;createUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&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;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;users&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="nx"&gt;user&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="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;findUserByEmail&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&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;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;u&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;findUserByEmail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Handle business logic:&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;// src/controllers/userController.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&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;bcrypt&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;jwt&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;jsonwebtoken&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;findUserByEmail&lt;/span&gt; &lt;span class="p"&gt;}&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;../models/userModel&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;register&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&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;body&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="nf"&gt;findUserByEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&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="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Email already exists&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hashedPassword&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;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&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="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="nf"&gt;createUser&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;hashedPassword&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;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&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;user&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;login&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&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;body&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="nf"&gt;findUserByEmail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&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;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&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;password&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="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid credentials&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&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;id&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1h&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;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. Routes
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/routes/userRoutes.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&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;express&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt; &lt;span class="p"&gt;}&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;../controllers/userController&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;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/register&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Middleware
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Error Handling:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/middlewares/errorMiddleware.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;errorHandler&lt;/span&gt; &lt;span class="o"&gt;=&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="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="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stack&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;status&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="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;500&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;message&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="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Server Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;errorHandler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Authentication:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/middlewares/authMiddleware.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jwt&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;jsonwebtoken&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;protect&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;next&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;token&lt;/span&gt; &lt;span class="o"&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;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;token&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="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Not authorized&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&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;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Token invalid&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="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;protect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  9. Validation with Joi
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Example schema&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Joi&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;joi&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;registerSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&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;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Joi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;registerSchema&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply in controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;registerSchema&lt;/span&gt; &lt;span class="p"&gt;}&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;../utils/validation&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;registerSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&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;body&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;error&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="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;400&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;details&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  10. Testing Your API
&lt;/h2&gt;

&lt;p&gt;Use &lt;strong&gt;Jest&lt;/strong&gt; and &lt;strong&gt;Supertest&lt;/strong&gt; for integration tests:&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;// tests/user.test.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;request&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;supertest&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;app&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;../src/app&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="s1"&gt;User API&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;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should register a new user&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="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;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;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&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/v1/users/register&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&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;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;john@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;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;123456&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&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="nx"&gt;res&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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&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;Run tests:&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;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  11. Security Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Helmet&lt;/strong&gt; → set HTTP headers.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CORS&lt;/strong&gt; → allow only trusted origins.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limiting&lt;/strong&gt; → prevent abuse.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sanitize inputs&lt;/strong&gt; → prevent XSS/NoSQL injection.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTPS&lt;/strong&gt; → enforce encryption in production.
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  12. Deployment
&lt;/h2&gt;

&lt;p&gt;Options:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Containerization&lt;/strong&gt;: Dockerize API, deploy on Kubernetes or AWS ECS.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Process manager&lt;/strong&gt;: PM2 for zero-downtime restarts.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD&lt;/strong&gt;: GitHub Actions, GitLab CI, or Jenkins.
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:20-alpine&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 5000&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["node", "server.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  13. Logging &amp;amp; Monitoring
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Winston / Pino&lt;/strong&gt; → structured logs.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prometheus + Grafana&lt;/strong&gt; → metrics dashboards.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error reporting&lt;/strong&gt; → Sentry, LogRocket.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  14. Scaling to Production
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;cluster mode&lt;/strong&gt; (PM2 or Node.js cluster) to utilize CPU cores.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Horizontal scaling&lt;/strong&gt; → deploy multiple instances behind a load balancer.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database optimization&lt;/strong&gt; → connection pooling, read replicas, indexes.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caching&lt;/strong&gt; → Redis for session or query caching.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  15. Conclusion
&lt;/h2&gt;

&lt;p&gt;Building a REST API from zero to production requires more than just writing endpoints—it’s about &lt;strong&gt;architecture, security, testing, monitoring, and scalability&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;By following these best practices in Node.js and Express:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You create maintainable and secure APIs.
&lt;/li&gt;
&lt;li&gt;You ensure reliability for real-world workloads.
&lt;/li&gt;
&lt;li&gt;You are ready to scale to thousands or millions of users.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With consistent design, thorough testing, and production-aware deployments, your Node.js REST API becomes a foundation for robust, scalable backend systems.&lt;/p&gt;

</description>
      <category>node</category>
      <category>restapi</category>
      <category>express</category>
      <category>rest</category>
    </item>
    <item>
      <title>Scaling Node.js Applications to Millions of Users: A Practical Guide</title>
      <dc:creator>Md Mahbubur Rahman</dc:creator>
      <pubDate>Tue, 30 Sep 2025 05:19:40 +0000</pubDate>
      <link>https://forem.com/m-a-h-b-u-b/scaling-nodejs-applications-to-millions-of-users-a-practical-guide-3mpm</link>
      <guid>https://forem.com/m-a-h-b-u-b/scaling-nodejs-applications-to-millions-of-users-a-practical-guide-3mpm</guid>
      <description>&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Leverage Node.js strengths&lt;/strong&gt;: Its single-threaded, non-blocking I/O makes it ideal for handling massive concurrency, but scaling requires deliberate strategies.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go horizontal, not just vertical&lt;/strong&gt;: Scaling to millions of users demands clustering, load balancing, and stateless architecture across multiple servers.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache aggressively&lt;/strong&gt;: Use Redis, Memcached, and CDNs to reduce latency, offload databases, and serve frequent requests instantly.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design for real-time&lt;/strong&gt;: WebSockets, pub/sub, and event-driven messaging help scale live chat, gaming, and streaming workloads.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offload heavy tasks&lt;/strong&gt;: Background processing with queues (BullMQ, RabbitMQ, Kafka) keeps the event loop responsive.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale the database layer&lt;/strong&gt;: Replication, sharding, and polyglot persistence are essential for sustainable growth.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability is non-negotiable&lt;/strong&gt;: Logging, metrics, and tracing ensure bottlenecks are visible before outages occur.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resilience matters&lt;/strong&gt;: Circuit breakers, retries, and graceful shutdowns help applications survive under pressure.
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Scaling an application to handle millions of users is both a technical and architectural challenge. Node.js, with its event-driven and non-blocking I/O model, provides a strong foundation for building high-performance, scalable systems. However, scaling Node.js requires far more than just writing asynchronous code—it involves thoughtful design decisions around architecture, infrastructure, and operational practices.  &lt;/p&gt;

&lt;p&gt;This article provides a &lt;strong&gt;practical, battle-tested guide&lt;/strong&gt; to scaling Node.js applications for millions of users. Drawing from a decade of real-world software engineering experience, we’ll explore strategies across performance optimization, horizontal scaling, caching, real-time workloads, observability, and resilience.  &lt;/p&gt;

&lt;h2&gt;
  
  
  1. Understanding Node.js Performance Model
&lt;/h2&gt;

&lt;p&gt;Node.js runs on a &lt;strong&gt;single-threaded event loop&lt;/strong&gt;. This makes it excellent for I/O-bound workloads (like API calls, DB queries, or file reads) but limited for CPU-bound tasks.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Key Implications:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Avoid long-running synchronous operations—they block the entire loop.
&lt;/li&gt;
&lt;li&gt;Heavy computations should be moved to worker threads or external services.
&lt;/li&gt;
&lt;li&gt;Scaling means distributing load across &lt;strong&gt;multiple Node.js processes&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Horizontal Scaling with Clustering
&lt;/h2&gt;

&lt;p&gt;Node.js doesn’t natively use multiple CPU cores. To leverage them, we use clustering.&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;cluster&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;cluster&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;os&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;os&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isMaster&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;numCPUs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cpus&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;numCPUs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="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;./server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Your app&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:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spawns a worker per CPU core.
&lt;/li&gt;
&lt;li&gt;Distributes incoming requests among workers.
&lt;/li&gt;
&lt;li&gt;Prevents one blocked worker from stalling the entire app.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For &lt;strong&gt;production-grade scaling&lt;/strong&gt;, combine clustering with:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;NGINX / HAProxy / AWS ALB&lt;/strong&gt; for load balancing.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PM2&lt;/strong&gt; process manager for zero-downtime reloads.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Stateless Architecture &amp;amp; Load Balancing
&lt;/h2&gt;

&lt;p&gt;To scale horizontally across servers, apps must be &lt;strong&gt;stateless&lt;/strong&gt;.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store sessions in &lt;strong&gt;Redis/Memcached&lt;/strong&gt;, not local memory.
&lt;/li&gt;
&lt;li&gt;Use shared storage (S3, GCS) for static assets.
&lt;/li&gt;
&lt;li&gt;Employ a &lt;strong&gt;load balancer&lt;/strong&gt; to distribute requests.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Diagram: Stateless Scaling&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Client -&amp;gt; Load Balancer -&amp;gt; [ Node.js App 1 ]
                                [ Node.js App 2 ]
                                [ Node.js App 3 ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Caching Strategies
&lt;/h2&gt;

&lt;p&gt;Caching reduces load and improves response times dramatically.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Application caching&lt;/strong&gt;: Cache DB queries in Redis.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Delivery Network (CDN)&lt;/strong&gt;: Cache static files globally.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database caching&lt;/strong&gt;: Use query-level caching.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example: Redis cache wrapper&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;redis&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;redis&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;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;fetchFn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;client&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="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &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="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;resolve&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="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchFn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3600&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="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="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;
  
  
  5. Offloading Heavy Workloads
&lt;/h2&gt;

&lt;p&gt;To keep Node.js responsive, heavy or long-running tasks should be moved to background workers.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Use Job Queues:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BullMQ (Redis-based)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RabbitMQ&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kafka&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example with BullMQ:&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;Queue&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;bull&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;videoQueue&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;Queue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;video transcoding&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;videoQueue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;video&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input.mp4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;videoQueue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;job&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Processing job:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;job&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Real-Time Scaling with WebSockets
&lt;/h2&gt;

&lt;p&gt;Node.js shines in real-time apps like chat or gaming.  &lt;/p&gt;

&lt;p&gt;Challenges arise when scaling WebSocket connections across multiple servers.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;Redis Pub/Sub&lt;/strong&gt; or &lt;strong&gt;Socket.IO Adapter&lt;/strong&gt; for distributed messaging.
&lt;/li&gt;
&lt;li&gt;For millions of users, consider &lt;strong&gt;Kafka&lt;/strong&gt; or &lt;strong&gt;NATS&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Diagram: WebSocket Scaling&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User -&amp;gt; LB -&amp;gt; Node.js Server 1 &amp;lt;-&amp;gt; Redis Pub/Sub &amp;lt;-&amp;gt; Node.js Server 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  7. Scaling the Database Layer
&lt;/h2&gt;

&lt;p&gt;Databases are often the first bottleneck.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vertical scaling&lt;/strong&gt;: Bigger machines (limited).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replication&lt;/strong&gt;: Read replicas for queries.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sharding&lt;/strong&gt;: Split data across nodes.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Polyglot persistence&lt;/strong&gt;: Use SQL for transactions, NoSQL for scale.
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;User auth in PostgreSQL.
&lt;/li&gt;
&lt;li&gt;Session + caching in Redis.
&lt;/li&gt;
&lt;li&gt;Analytics in ClickHouse.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  8. Observability: Logs, Metrics, Traces
&lt;/h2&gt;

&lt;p&gt;You can’t scale what you can’t measure.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Centralized Logging&lt;/strong&gt;: Elastic Stack, Loki, or Datadog.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Metrics&lt;/strong&gt;: Prometheus + Grafana dashboards.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Distributed Tracing&lt;/strong&gt;: OpenTelemetry, Jaeger.
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Request latency (p95, p99).
&lt;/li&gt;
&lt;li&gt;Event loop lag.
&lt;/li&gt;
&lt;li&gt;Memory usage &amp;amp; GC pauses.
&lt;/li&gt;
&lt;li&gt;Database query times.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9. Building Resilient Node.js Systems
&lt;/h2&gt;

&lt;p&gt;Scaling isn’t just about speed—it’s also about &lt;strong&gt;stability&lt;/strong&gt;.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Patterns for Resilience:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Circuit Breakers&lt;/strong&gt; (e.g., &lt;code&gt;opossum&lt;/code&gt; library).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retries with backoff&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limiting&lt;/strong&gt; (via NGINX or libraries).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Graceful shutdowns&lt;/strong&gt;: Stop taking new requests, finish active ones.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  10. Case Study: Scaling a Chat Application
&lt;/h2&gt;

&lt;p&gt;Imagine a global chat platform with millions of concurrent users.  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Frontend CDN&lt;/strong&gt; serves static assets.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.js cluster&lt;/strong&gt; handles WebSocket connections.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis Pub/Sub&lt;/strong&gt; synchronizes messages.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kafka&lt;/strong&gt; pipelines stream logs and metrics.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database layer&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;PostgreSQL for user accounts.
&lt;/li&gt;
&lt;li&gt;Redis for sessions.
&lt;/li&gt;
&lt;li&gt;ElasticSearch for chat history search.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This architecture supports millions of concurrent users reliably.  &lt;/p&gt;

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

&lt;p&gt;Scaling Node.js applications to millions of users requires &lt;strong&gt;holistic engineering&lt;/strong&gt;: from leveraging clustering and caching, to managing state, to scaling databases and ensuring observability.  &lt;/p&gt;

&lt;p&gt;The goal isn’t just raw throughput but &lt;strong&gt;resilient, maintainable, and cost-efficient systems&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;With the right architecture and practices, Node.js can power applications serving &lt;strong&gt;millions of users worldwide&lt;/strong&gt;—from real-time messaging to APIs at global scale.  &lt;/p&gt;

</description>
      <category>node</category>
      <category>websocket</category>
      <category>redis</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Why PHP frameworks often (still) perform slower than Python / Go / Rust / Java frameworks</title>
      <dc:creator>Md Mahbubur Rahman</dc:creator>
      <pubDate>Mon, 29 Sep 2025 14:16:55 +0000</pubDate>
      <link>https://forem.com/m-a-h-b-u-b/why-php-frameworks-often-still-perform-slower-than-python-go-rust-java-frameworks-4457</link>
      <guid>https://forem.com/m-a-h-b-u-b/why-php-frameworks-often-still-perform-slower-than-python-go-rust-java-frameworks-4457</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR (quick summary)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Raw microbenchmark results&lt;/strong&gt; (&lt;a href="https://www.techempower.com/benchmarks/" rel="noopener noreferrer"&gt;TechEmpower Web Framework Benchmarks&lt;/a&gt;) repeatedly show compiled-oriented stacks (Go, Rust, high-tuned Java/.NET) delivering &lt;strong&gt;orders of magnitude higher requests/sec&lt;/strong&gt; than typical PHP frameworks (Laravel, Symfony) in best-case, in-memory tests. This often looks like &lt;em&gt;10–30×&lt;/em&gt; or more advantage for the fastest Go/Rust/Java frameworks on simple JSON/hello-world tests.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PHP has closed the gap&lt;/strong&gt; significantly with PHP 7/8 (OPcache, JIT, optimization) — real PHP app throughput improved materially (and PHP 8.3 produced measurable additional gains), but the language/runtime and typical framework patterns still favor developer productivity over raw throughput. Expect &lt;strong&gt;tens of percent&lt;/strong&gt; improvement from version upgrades, not orders-of-magnitude parity in microbenchmarks.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In real apps&lt;/strong&gt; (DB I/O, network, templates, caching), language differences often shrink — the dominant cost is I/O and architecture, not pure request CPU — so &lt;strong&gt;measured field performance can be much closer&lt;/strong&gt; than microbenchmarks suggest. “Test your app” still holds.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What the authoritative benchmarks show (and how to read them)
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.techempower.com/benchmarks/" rel="noopener noreferrer"&gt;TechEmpower Framework Benchmarks (TFB)&lt;/a&gt; are the standard public comparison for raw framework throughput/latency across many languages and frameworks. TFB runs focused scenarios such as plaintext, JSON serialization, single-query and multiple-query database access, and updates. The winners on &lt;em&gt;pure throughput&lt;/em&gt; consistently include highly-tuned frameworks written in &lt;strong&gt;Rust, Go, C#, and specialized Java stacks&lt;/strong&gt;, while typical PHP frameworks sit much lower in raw throughput rankings.&lt;/p&gt;

&lt;p&gt;A convenient public synthesis of TFB results shows the common pattern: on the simplest, CPU-bound endpoints (plaintext/JSON), the fastest Go/Rust/Java stacks can achieve &lt;strong&gt;10–30×&lt;/strong&gt; the requests/second of baseline PHP frameworks in the same environment; in some TFB permutations the top .NET or Go implementations score &lt;strong&gt;20–40×&lt;/strong&gt; compared to a typical Laravel example. That’s &lt;em&gt;microbenchmark&lt;/em&gt; territory — heavily optimized, minimal handlers, and tuned I/O stacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important nuance&lt;/strong&gt;: TFB is extremely useful to compare language/runtime overhead and framework internals &lt;em&gt;on tiny handlers&lt;/em&gt;. It doesn’t necessarily reflect a real site that spends 90% of time in DB queries, remote APIs, or template rendering. Many engineers overextend TFB conclusions to full-stack applications, which is where caution is needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why PHP tends to lag in these microbenchmarks — technical reasons
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Runtime model: interpreted/VM vs ahead-of-time compiled code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Languages like &lt;strong&gt;Go&lt;/strong&gt; produce native binaries with simple, efficient concurrency primitives; &lt;strong&gt;Rust&lt;/strong&gt; compiles to native code that eliminates runtime costs; &lt;strong&gt;Java&lt;/strong&gt;/JVM uses highly-optimized JIT and mature GC tuned for server workloads. PHP historically executes via an interpreter/bytecode VM, with OPcache reducing parse time but still running per-request execution logic unless using long-running process models. That execution model can add CPU overhead per request in synthetic tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Implication:&lt;/strong&gt; native code + low runtime overhead wins in microbenchmarks.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Process / threading model and long-running services
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Go and Rust frameworks commonly run as a single long-running process with evented or lightweight-thread scheduling handling many connections in the same process memory; that reduces context switching, repeated boot costs, memory churn, and allocation/deallocation overhead. Traditional PHP (Zend + FPM) uses a pool of short-lived worker processes where each logical request executes PHP code from start to finish in an isolated process — this model isolates faults and simplifies lifecycle, but it increases per-request overhead relative to a single-binary approach. (Note: modern PHP alternatives — Swoole, RoadRunner — provide long-running models to close this gap.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Implication:&lt;/strong&gt; process model matters — long-running evented runtimes are more efficient for microbenchmarks.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Autoloading, reflection, and heavy framework abstractions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;PHP ecosystems rely heavily on Composer autoloaders, heavy middleware stacks, large ORMs (Eloquent, Doctrine) and dependency injection. Those abstractions improve developer productivity but add CPU and memory overhead per request (class resolution, reflection, metadata parsing). In minimal TFB handlers the overhead is proportionally larger; engineered Go/Rust “hello” handlers are literally a few syscalls.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Implication:&lt;/strong&gt; framework design choices (convenience vs minimalism) directly shape microbenchmark results.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Garbage collection and allocation patterns
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Modern JVMs and Go’s runtime include well-tuned GC/heap strategies designed for long-running server applications. Rust has no runtime GC and enables zero-cost abstractions. PHP’s memory allocator and garbage collection were designed for the classic request lifecycle; while OPcache and improvements have helped, in microbenchmarks the allocation/collection behavior is less optimal than specialized server runtimes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. I/O stacks and async support
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Historically PHP lacked first-class async primitives; while frameworks and libs (ReactPHP, Amp, Swoole) added async/evented capabilities, the mainstream frameworks and libraries are still mostly sync/blocking in style. Go has concurrency primitives in the language; async I/O is idiomatic and lightweight. This means that out of the box, PHP frameworks can be blocked on I/O more often and it’s harder to expose efficient concurrency in a typical app.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Implication:&lt;/strong&gt; native concurrency support in languages leads to better utilization under concurrency.&lt;/p&gt;

&lt;h2&gt;
  
  
  What changed: PHP 7/8 and the JIT — improvements and limits
&lt;/h2&gt;

&lt;p&gt;The community saw a major leap with &lt;strong&gt;PHP 7&lt;/strong&gt; (engine internals, reduced memory usage) and continued improvements with &lt;strong&gt;PHP 8+&lt;/strong&gt;: OPcache, preloading, incremental JIT, and language optimizations cut per-request costs substantially. Vendors and benchmarking articles (&lt;a href="https://kinsta.com/blog/php-8-3/" rel="noopener noreferrer"&gt;Kinsta&lt;/a&gt;) have measured &lt;em&gt;significant&lt;/em&gt; gains when upgrading minor versions (e.g., PHP 8.3 yields up to ~38% gain over 8.2 for specific Laravel demo workloads). But note that these are version-upgrade &lt;em&gt;gains&lt;/em&gt;, not a change in the architectural nature of PHP.&lt;/p&gt;

&lt;p&gt;Meta (Facebook) developed HHVM and Hack historically to address PHP’s performance and scale needs; many of HHVM’s ideas influenced later PHP optimizations. For massive proprietary deployments, organizations have built custom compilers/C++ runtimes and extensive platform optimizations — but those are not off-the-shelf PHP framework wins for most teams.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Net effect:&lt;/strong&gt; PHP is much faster than a decade ago — but the remaining structural differences still show in tight microbenchmarks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Numbers: realistic percentage comparisons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;TechEmpower (microbenchmarks / round results):&lt;/strong&gt; fastest Go/Rust/.NET frameworks frequently outpace typical PHP frameworks by &lt;strong&gt;an order of magnitude or more&lt;/strong&gt; on plaintext and JSON tests (&lt;a href="https://github.com/TechEmpower/FrameworkBenchmarks" rel="noopener noreferrer"&gt;TechEmpower GitHub&lt;/a&gt;).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version upgrade gains within PHP:&lt;/strong&gt; upgrading a real app to &lt;strong&gt;PHP 8.3&lt;/strong&gt; from 8.2 showed &lt;strong&gt;~38%&lt;/strong&gt; improvement in specific Laravel demos (&lt;a href="https://kinsta.com/blog/php-8-3/" rel="noopener noreferrer"&gt;Kinsta&lt;/a&gt;).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Field/real-world caveat:&lt;/strong&gt; independent WordPress/Drupal benchmarks show &lt;strong&gt;app-specific&lt;/strong&gt; variability — properly tuned PHP setups can deliver comparable latency under realistic loads (&lt;a href="https://www.jeffgeerling.com/blog" rel="noopener noreferrer"&gt;Jeff Geerling Dev Blog&lt;/a&gt;).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous benchmarking status:&lt;/strong&gt; TechEmpower’s continuous runner shows coverage across hundreds of implementations (&lt;a href="https://www.techempower.com/benchmarks/" rel="noopener noreferrer"&gt;TechEmpower Benchmarks&lt;/a&gt;).&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Bottom line: in &lt;strong&gt;synthetic CPU-bound&lt;/strong&gt; tests the top Go/Rust/Java frameworks commonly reach &lt;strong&gt;10×–30×&lt;/strong&gt; the throughput of typical PHP frameworks; in &lt;strong&gt;real I/O-bound&lt;/strong&gt; apps, differences narrow and are often measured in &lt;strong&gt;single to low-double-digit percents&lt;/strong&gt; after architecture and caching are considered.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Practical engineering implications
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CPU-bound requests:&lt;/strong&gt; Go/Rust/Java for hot paths.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I/O-bound apps:&lt;/strong&gt; PHP is usually sufficient if tuned.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer velocity/ecosystem:&lt;/strong&gt; PHP frameworks excel; consider hybrid microservices for critical paths.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Closing the gap in PHP
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Upgrade PHP to 8.x + enable OPcache + preloading.
&lt;/li&gt;
&lt;li&gt;Use long-running process options (Swoole, RoadRunner).
&lt;/li&gt;
&lt;li&gt;Offload CPU-heavy endpoints to Go/Rust.
&lt;/li&gt;
&lt;li&gt;Cache aggressively.
&lt;/li&gt;
&lt;li&gt;Profile and optimize framework code.
&lt;/li&gt;
&lt;li&gt;Use FFI/natively compiled extensions for hot functions.
&lt;/li&gt;
&lt;li&gt;Tune server/platform (network, nginx, FPM pools).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Sources &amp;amp; further reading
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.techempower.com/benchmarks/" rel="noopener noreferrer"&gt;TechEmpower Web Framework Benchmarks&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/TechEmpower/FrameworkBenchmarks" rel="noopener noreferrer"&gt;TechEmpower GitHub FrameworkBenchmarks&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kinsta.com/blog/php-8-3/" rel="noopener noreferrer"&gt;Kinsta: PHP 8.3 Performance&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://tideways.com/profiler/blog/php-benchmarks-8-4-performance-is-steady-compared-to-8-3-and-8-2" rel="noopener noreferrer"&gt;Tideways PHP Benchmarks&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.jeffgeerling.com/blog" rel="noopener noreferrer"&gt;Jeff Geerling: WordPress/Drupal PHP Performance&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/tuananhpham/popular-backend-frameworks-performance-benchmark-1bkh"&gt;Dev.to: Backend Frameworks Performance Analysis&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>php</category>
      <category>go</category>
      <category>rust</category>
      <category>python</category>
    </item>
    <item>
      <title>Why eFuses Matter in Firmware Security: Permanent Storage, Anti-Rollback, and Device Identity</title>
      <dc:creator>Md Mahbubur Rahman</dc:creator>
      <pubDate>Fri, 26 Sep 2025 01:17:03 +0000</pubDate>
      <link>https://forem.com/m-a-h-b-u-b/why-efuses-matter-in-firmware-security-permanent-storage-anti-rollback-and-device-identity-4fon</link>
      <guid>https://forem.com/m-a-h-b-u-b/why-efuses-matter-in-firmware-security-permanent-storage-anti-rollback-and-device-identity-4fon</guid>
      <description>&lt;h2&gt;
  
  
  1. What Exactly Are eFuses / OTP Memory?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;One-Time-Programmable (OTP) memory&lt;/strong&gt; is non-volatile storage that can be written exactly once (or in some variations: written in a monotonic direction, e.g., 0→1 only) after manufacture and then permanently locked.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;eFuse&lt;/strong&gt; is a common implementation that uses intentionally weak metal or silicon traces permanently altered by a programming event (electromigration or thermal runaway), changing the electrical state for that bit. Other OTP technologies include antifuse (off→on when programmed) and floating-gate PROM variants.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important distinctions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;eFuse (electronic fuse):&lt;/strong&gt; typically stores a default logic value (often “1”) and the programming event blows/changes the trace to produce the opposite state. Programming is irreversible.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Antifuse:&lt;/strong&gt; default is open / 0, programming creates a conductive link producing a 1.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Not to be confused with power eFuses:&lt;/strong&gt; different devices used as electronic current-limit switches.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Why eFuses Matter (Practical Reasons)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Immutable root-of-trust anchors:&lt;/strong&gt; Store public keys (ROTPK), secure-boot enable/disable flags, or immutable device certificates.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anti-rollback &amp;amp; lifecycle state:&lt;/strong&gt; Record firmware version thresholds or device lifecycle states.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unique device identity:&lt;/strong&gt; Burn factory MAC addresses, unique IDs, or serial numbers that must never change.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permanent calibration/trim for analog/performance:&lt;/strong&gt; Store factory calibration constants and trimming values.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cheap, small area for essential bits:&lt;/strong&gt; Occupies less silicon and consumes less leakage than flash or EEPROM for small numbers of bits.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified manufacturing &amp;amp; provisioning flows:&lt;/strong&gt; One-shot programming step simplifies test, burn-in, and field security models.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  3. How eFuses Are Used in Real Products
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Secure boot flags and keys:&lt;/strong&gt; Many chip vendors expose eFuse banks to enable secure boot and store public keys or key digests.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embedded connectivity modules:&lt;/strong&gt; Programming MAC address and disabling recovery modes via eFuses prevents flash replacement attacks.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microcontrollers (ESP32 family):&lt;/strong&gt; Espressif’s eFuse manager API defines, burns, and reads eFuses for MACs, encryption keys, and feature disables (e.g., JTAG).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Engineering Tradeoffs
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;Permanence = tamper resistance and anti-rollback.&lt;/li&gt;
&lt;li&gt;Low area &amp;amp; low standby power for small number of bits.&lt;/li&gt;
&lt;li&gt;Simple programming model (one shot).&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No rewrites:&lt;/strong&gt; Mistaken programming is catastrophic.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Limited capacity:&lt;/strong&gt; Not suitable for large data.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Programming complexity / yield risks:&lt;/strong&gt; Requires precise voltage/current profiles.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Side-channel and physical attacks:&lt;/strong&gt; On-chip eFuses are still vulnerable to invasive attacks; secure elements or TPMs provide stronger protections.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. eFuses vs Other Storage Options — Side-by-Side
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Attribute / Tech&lt;/th&gt;
&lt;th&gt;eFuses (OTP)&lt;/th&gt;
&lt;th&gt;Antifuse (OTP)&lt;/th&gt;
&lt;th&gt;Flash / EEPROM&lt;/th&gt;
&lt;th&gt;Secure Element / TPM&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Immutability / anti-rollback&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;td&gt;90%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Programmability flexibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;td&gt;40%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Area / cost for few bits&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;90%&lt;/td&gt;
&lt;td&gt;85%&lt;/td&gt;
&lt;td&gt;30%&lt;/td&gt;
&lt;td&gt;50%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Power (standby)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;90%&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;td&gt;50%&lt;/td&gt;
&lt;td&gt;70%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Resistance to firmware replacement attack&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;90%&lt;/td&gt;
&lt;td&gt;90%&lt;/td&gt;
&lt;td&gt;10%&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ease of production programming&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;70%&lt;/td&gt;
&lt;td&gt;60%&lt;/td&gt;
&lt;td&gt;85%&lt;/td&gt;
&lt;td&gt;40%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;High-assurance protection / certifications&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;40%&lt;/td&gt;
&lt;td&gt;40%&lt;/td&gt;
&lt;td&gt;30%&lt;/td&gt;
&lt;td&gt;95%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;ul&gt;
&lt;li&gt;eFuses and antifuses are functionally similar for permanence.
&lt;/li&gt;
&lt;li&gt;Flash/EEPROM is best for mutability and capacity.
&lt;/li&gt;
&lt;li&gt;Secure elements offer far stronger physical protection and certified algorithms.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. When to Use eFuses
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use eFuses when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need a permanent anchor for the boot chain (ROTPK, secure-boot enable, anti-rollback markers).
&lt;/li&gt;
&lt;li&gt;Factory-programmed unique identity must never change.
&lt;/li&gt;
&lt;li&gt;Trim/calibration constants must be immutable.
&lt;/li&gt;
&lt;li&gt;Minimal area/power is essential.
&lt;/li&gt;
&lt;li&gt;You can handle operational constraints (production programming, test hooks, recovery strategies).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Avoid eFuses when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configuration changes over the device lifecycle.
&lt;/li&gt;
&lt;li&gt;You need certified cryptographic protections beyond what on-chip fuses can provide.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. Production &amp;amp; Provisioning Best Practices
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Design for staged locking:&lt;/strong&gt; Separate fuse regions or per-feature bits; use development flags during iteration.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shadow &amp;amp; verification:&lt;/strong&gt; Program provisional shadow bits and verify multiple times.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automate with calibrated programming rigs:&lt;/strong&gt; Control pulse profiles and verify reads.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provide test modes during early runs:&lt;/strong&gt; Avoid irreversible flags until firmware flows are stable.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan for lost keys / RMA:&lt;/strong&gt; Account for irreversible bits in replacement strategy.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document eFuse map &amp;amp; reserve bits:&lt;/strong&gt; Leave spare monotonic bits for future policies.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  8. Security Considerations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;eFuses protect against firmware replacement but are not immune to invasive attacks.
&lt;/li&gt;
&lt;li&gt;Side-channel or fault-injection attacks could attempt to flip bits; include verification and tamper detection.
&lt;/li&gt;
&lt;li&gt;Avoid storing raw secret keys accessible to buses; prefer key digests or sealed keys inside secure enclaves.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  9. Industry Specs &amp;amp; Ecosystem Notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vendor docs:&lt;/strong&gt; Espressif, Silicon Labs, NXP, and TI provide eFuse APIs, mapping, and programming guides.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security architecture standards:&lt;/strong&gt; ARM’s PSA recommends hardware anchors like eFuses for roots of trust.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technology selection:&lt;/strong&gt; Synopsys, SemiEngineering, and other semiconductor IP sources discuss eFuse, antifuse, and floating-gate OTP tradeoffs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  10. Practical Checklist Before Committing to eFuses
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Map which bits must be immutable vs changeable.
&lt;/li&gt;
&lt;li&gt;Implement development → production locking plan.
&lt;/li&gt;
&lt;li&gt;Ensure production programming hardware is qualified.
&lt;/li&gt;
&lt;li&gt;Budget spare bits for future policies.
&lt;/li&gt;
&lt;li&gt;Evaluate whether high-assurance protection (FIPS/CC) is required.
&lt;/li&gt;
&lt;li&gt;Test recovery and RMA flows.
&lt;/li&gt;
&lt;li&gt;Validate robustness against injection/glitch faults.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  11. Realistic Example: Secure Boot + Anti-Rollback Flow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Develop with secure boot disabled and use mutable flash to test images.
&lt;/li&gt;
&lt;li&gt;In production, program eFuses: burn ROTPK hash, set secure-boot enable, set anti-rollback version bits.
&lt;/li&gt;
&lt;li&gt;Boot ROM checks eFuse ROTPK before validating bootloader signature; bootloader checks firmware signature and anti-rollback values.
&lt;/li&gt;
&lt;li&gt;Because eFuses are immutable, attackers cannot downgrade firmware without violating anti-rollback bits.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  12. Closing Guidance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Treat eFuses as &lt;strong&gt;policy anchors&lt;/strong&gt;, not mutable configuration.
&lt;/li&gt;
&lt;li&gt;Keep the eFuse map minimal: keys, anti-rollback, device ID, and few policy toggles.
&lt;/li&gt;
&lt;li&gt;Use eFuses to &lt;strong&gt;simplify trust&lt;/strong&gt;, making firmware overwrite attacks harder.
&lt;/li&gt;
&lt;li&gt;For high-assurance applications, combine eFuses with secure elements and follow formal provisioning/certification processes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Selected References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Espressif: eFuse Manager / efuse API (ESP32 family)
&lt;/li&gt;
&lt;li&gt;Silicon Labs: AN1442 Secure Boot with Anti-Rollback (eFuse examples)
&lt;/li&gt;
&lt;li&gt;Synopsys: OTP NVM article (eFuse/antifuse/floating-gate comparisons)
&lt;/li&gt;
&lt;li&gt;SemiEngineering: One-Time Programmable memory overview and antifuse benefits&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>efuses</category>
      <category>firmwire</category>
      <category>security</category>
      <category>iot</category>
    </item>
    <item>
      <title>High-Performance App Development: Why Top Engineers Skip PHP for Modern Stacks</title>
      <dc:creator>Md Mahbubur Rahman</dc:creator>
      <pubDate>Thu, 25 Sep 2025 04:53:14 +0000</pubDate>
      <link>https://forem.com/m-a-h-b-u-b/high-performance-app-development-why-top-engineers-skip-php-for-modern-stacks-259a</link>
      <guid>https://forem.com/m-a-h-b-u-b/high-performance-app-development-why-top-engineers-skip-php-for-modern-stacks-259a</guid>
      <description>&lt;p&gt;This article explains &lt;strong&gt;why PHP is often avoided&lt;/strong&gt; in &lt;em&gt;high-performance / high-scale systems&lt;/em&gt;, presents &lt;strong&gt;percentage-based comparisons&lt;/strong&gt;, and suggests &lt;strong&gt;better alternatives&lt;/strong&gt; with reasoning.&lt;br&gt;&lt;br&gt;
&lt;em&gt;(Perspective: 10+ years of software engineering experience)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What “High Performance” Implies
&lt;/h2&gt;

&lt;p&gt;High-performance web or system apps typically require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High throughput &amp;amp; low latency&lt;/strong&gt; (many requests/sec).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low resource usage&lt;/strong&gt; (CPU, memory, I/O overhead).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Excellent concurrency&lt;/strong&gt; (thousands of simultaneous connections).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time behavior&lt;/strong&gt; (websockets, streaming, push).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Predictable scaling&lt;/strong&gt; (vertical &amp;amp; horizontal).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why PHP Is &lt;em&gt;Often&lt;/em&gt; Not the First Choice
&lt;/h2&gt;

&lt;p&gt;PHP is great for content-oriented websites (CMS, blogs, e-commerce) but its architecture and history introduce limitations.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Limitation&lt;/th&gt;
&lt;th&gt;Root Cause&lt;/th&gt;
&lt;th&gt;Approx. Impact&lt;/th&gt;
&lt;th&gt;When It Hurts Most&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Blocking / synchronous request model&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Each HTTP request runs in its own process/thread; blocking I/O.&lt;/td&gt;
&lt;td&gt;Reduces throughput by &lt;strong&gt;30-80%&lt;/strong&gt; vs event-driven runtimes.&lt;/td&gt;
&lt;td&gt;High concurrency, long I/O operations.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Startup &amp;amp; memory overhead&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Each request reloads framework, autoloaders, etc.&lt;/td&gt;
&lt;td&gt;Adds &lt;strong&gt;10-40%&lt;/strong&gt; latency vs always-on services.&lt;/td&gt;
&lt;td&gt;Many small API calls, microservices.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Weak for CPU-intensive tasks&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Interpreted, dynamic typing, heavier GC.&lt;/td&gt;
&lt;td&gt;Typically &lt;strong&gt;2–5× slower&lt;/strong&gt; than Go/Java/Rust.&lt;/td&gt;
&lt;td&gt;Heavy computation, analytics, ML, image/video processing.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Limited concurrency / real-time&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stateless request handling, long-lived connections awkward.&lt;/td&gt;
&lt;td&gt;Real-time/websocket overhead can be &lt;strong&gt;2×+&lt;/strong&gt; vs event-driven stacks.&lt;/td&gt;
&lt;td&gt;Chat, streaming, push notifications.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scaling cost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Needs many workers, each with memory &amp;amp; startup overhead.&lt;/td&gt;
&lt;td&gt;Infra cost can be &lt;strong&gt;30–100% higher&lt;/strong&gt; to match Go/Node throughput.&lt;/td&gt;
&lt;td&gt;Traffic spikes, massive horizontal scaling.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Async ecosystem maturity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Async libraries exist but less idiomatic than Node/Go/Rust.&lt;/td&gt;
&lt;td&gt;Throughput loss of &lt;strong&gt;tens of percent&lt;/strong&gt; for I/O heavy tasks.&lt;/td&gt;
&lt;td&gt;High I/O loads, many downstream API calls.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Improvements That Help
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PHP 7+&lt;/strong&gt;: major throughput/memory gains over PHP 5.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PHP 8 (JIT)&lt;/strong&gt;: some boost for numeric workloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OPcache&lt;/strong&gt;: reduces per-request startup.&lt;/li&gt;
&lt;li&gt;Well-tuned Laravel/Symfony or barebones PHP can be “good enough” for many moderate-load apps.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Better Alternatives and Why
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Alternative&lt;/th&gt;
&lt;th&gt;Why It’s Better&lt;/th&gt;
&lt;th&gt;Typical Performance Gain vs PHP&lt;/th&gt;
&lt;th&gt;Ideal Use Cases&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Go (Golang)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Compiled, lightweight goroutines, efficient GC.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;2–5× throughput&lt;/strong&gt;, ~40–70% less CPU/memory.&lt;/td&gt;
&lt;td&gt;High-concurrency APIs, microservices, cloud-native backends.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Node.js / Deno&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Event-driven non-blocking I/O.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;2–4× better&lt;/strong&gt; under I/O-bound load.&lt;/td&gt;
&lt;td&gt;Real-time apps, websockets, streaming, API gateways.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Java / Kotlin (JVM)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;HotSpot JIT, mature concurrency, enterprise ecosystem.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;2–10× faster&lt;/strong&gt; for compute-heavy logic.&lt;/td&gt;
&lt;td&gt;Large enterprise services, long-running APIs, complex business logic.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rust&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Native speed, zero-cost abstractions, memory safety.&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;5–20× faster&lt;/strong&gt; and far lower memory footprint.&lt;/td&gt;
&lt;td&gt;Ultra-low latency services, binary data processing, high-frequency trading.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;C# / .NET Core&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High-performance runtime, great concurrency support.&lt;/td&gt;
&lt;td&gt;Often &lt;strong&gt;2–5×&lt;/strong&gt; throughput improvements.&lt;/td&gt;
&lt;td&gt;Enterprise backends, cross-platform web APIs.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Python (FastAPI/ASGI)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Rich ecosystem; not inherently faster but productive.&lt;/td&gt;
&lt;td&gt;Often &lt;strong&gt;slower&lt;/strong&gt; than PHP unless optimized, but excels in ML/data.&lt;/td&gt;
&lt;td&gt;Data science, ML, quick backend prototypes.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  %-Based Comparison (Typical Scenarios)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;PHP (Optimized)&lt;/th&gt;
&lt;th&gt;Alternatives&lt;/th&gt;
&lt;th&gt;Improvement&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;High-concurrency API&lt;/td&gt;
&lt;td&gt;baseline&lt;/td&gt;
&lt;td&gt;Go/Rust/Node &lt;strong&gt;~2–4× throughput&lt;/strong&gt;, &lt;strong&gt;30–60% lower latency&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Significant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heavy compute (e.g., image processing)&lt;/td&gt;
&lt;td&gt;baseline&lt;/td&gt;
&lt;td&gt;Go/Rust/Java &lt;strong&gt;~5–20× faster&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Critical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Real-time connections (websockets)&lt;/td&gt;
&lt;td&gt;baseline&lt;/td&gt;
&lt;td&gt;Node/Go &lt;strong&gt;handles tens of thousands of connections effortlessly&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Major&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory usage per concurrent request&lt;/td&gt;
&lt;td&gt;Higher (per-process autoload)&lt;/td&gt;
&lt;td&gt;Go/Rust lower by &lt;strong&gt;30–70%&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Cost saving&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  When PHP Is Still Fine
&lt;/h2&gt;

&lt;p&gt;PHP remains viable when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Content-heavy&lt;/strong&gt; sites with strong caching (CMS, e-commerce).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Moderate traffic&lt;/strong&gt;, manageable scaling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rapid development&lt;/strong&gt; and huge ecosystem (Laravel, WordPress).&lt;/li&gt;
&lt;li&gt;Existing skilled PHP teams and codebases.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Decision Matrix
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criterion&lt;/th&gt;
&lt;th&gt;Stay with PHP&lt;/th&gt;
&lt;th&gt;Move to Alternative&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Moderate traffic, good caching&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thousands of concurrent connections&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Heavy CPU/compute tasks&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ultra-low latency required&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Need async microservices/cloud-native&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Legacy PHP codebase, quick iteration&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modern PHP is far better&lt;/strong&gt; than it once was, but its request-per-process model and weaker async/concurrency support limit extreme performance.&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;high-concurrency, real-time, or compute-intensive workloads&lt;/strong&gt;, Go, Rust, Node.js, Java/Kotlin, or .NET Core routinely deliver &lt;strong&gt;2–5×&lt;/strong&gt; (or more) throughput and latency improvements and often &lt;strong&gt;30–70% lower infrastructure costs&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Many teams adopt a &lt;strong&gt;polyglot approach&lt;/strong&gt;: keep PHP for content or legacy parts, but offload performance-critical services to faster stacks.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Bottom line:&lt;/strong&gt; PHP can absolutely scale, but if you’re building &lt;em&gt;high-performance, low-latency, high-concurrency&lt;/em&gt; systems in 2025, &lt;strong&gt;Go, Rust, Node.js, Java/Kotlin, or .NET Core&lt;/strong&gt; are usually the stronger choices.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
  </channel>
</rss>
