<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: webdev</title>
    <description>The latest articles tagged 'webdev' on DEV Community.</description>
    <link>https://dev.to/t/webdev</link>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tag/webdev"/>
    <language>en</language>
    <item>
      <title>How I built an AI-enabled GitHub discovery tool</title>
      <dc:creator>adospace</dc:creator>
      <pubDate>Tue, 28 Apr 2026 14:52:29 +0000</pubDate>
      <link>https://dev.to/adospace/how-i-built-an-ai-enabled-github-discovery-tool-5h65</link>
      <guid>https://dev.to/adospace/how-i-built-an-ai-enabled-github-discovery-tool-5h65</guid>
      <description>&lt;p&gt;I am always in search of great GitHub repositories.&lt;/p&gt;

&lt;p&gt;I'm interested in learning new frameworks or tools, discovering niche but well-maintained projects, etc., but I'm also in a strange relationship with "GitHub trending lists", or "Top 10 trending repos in 2026" articles.&lt;br&gt;
Really do not help to know that that specific repo is skyrocketing stars metric, if it's dealing with an issue I don't have or using a tool/framework not on my radar. &lt;/p&gt;

&lt;p&gt;What if I just want to get a look at a production-ready project that could be useful for my work? Or learn a new language starting from a GitHub tutorial repo?&lt;/p&gt;

&lt;p&gt;Here's the deal:&lt;br&gt;
1) Take an AI agent powered by Claude.&lt;br&gt;
2) Provide him a prompt, specific to my interests, like "search and carefully select a few GH repositories that deal with Rust, native desktop development, not a webview/web wrapper, that are well-maintained".&lt;br&gt;
3) Run the agent time to time and let him pack a weekly delivered list of 3-5 repo links, with a short description, what is good, and what is less.&lt;/p&gt;

&lt;p&gt;I took the challenge using things I already know well, the .NET stack, the newly Anthropic SDK for c#, deliver on Azure, but not an App Service, or full-blown AKS, something that can run scheduled, serverless, cheap, yes, Azure Functions. For the web page to let users register their email and provide their interests in natural language, nothing better than an Azure static web page, no stack, just plain HTML+JS (yes was ugly, initially). SQL Server to save the user emails, mailing list, etc. &lt;/p&gt;

&lt;p&gt;With Claude's help, I got a working version (locally) in half a day.&lt;/p&gt;

&lt;p&gt;Now the tricky parts, I tried to run the web app (func start and swa start), the Claude API usage was really high! nothing that I could realistically put in production.&lt;/p&gt;

&lt;p&gt;Soon, I discovered that the Anthropic cache wasn't enabled. But even after enabling it, generating a single email would have cost almost 1$ (using Sonnet), far too high anyway.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ┌──────┐
   │ User │  "Find me Rust desktop repos"
   └──┬───┘
      │
      ▼
   ┌────────────────────────────────────────┐
   │              CLAUDE                    │
   │  search GitHub  →  read each repo  →   │
   │  judge  →  write the email             │
   └─────────────────┬──────────────────────┘
                     │
                     ▼
              ┌─────────────┐
              │    Email    │   ~$1 per user
              └─────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I tracked down the number of tokens spent to read/explore a single repo (using Octokit), and it was huge. But I thought, what if 2 or more users have similar interests? A repository explored for one user could have been of some interest for others, too. &lt;br&gt;
Why not create a cache of already explored repositories? &lt;br&gt;
So I created the table with all the useful info just discovered by the AI, and anytime it had to find repos for a user, it first had to look at the summarized versions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                       ┌──────────────────┐
                       │    Repo Cache    │
                       │  summary, 👍,👎 │
                       └────────▲─────────┘
                                │  tool calls
                                │  (query, read, decide)
   ┌──────┐          ┌──────────┴────────┐          ┌───────┐
   │ User │────────&amp;gt; │      CLAUDE       │────────&amp;gt; │ Email │
   └──────┘          └──────────┬────────┘          └───────┘
                                │  if cache thin
                                ▼
                       ┌──────────────────┐
                       │  GitHub  +  LLM  │
                       │   evaluation     │
                       │  (writes cache)  │
                       └──────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI costs have gotten better, but still too high. The real problem was that Claude had to navigate the cache itself, making incremental queries to find the interesting repositories, read the query result, and then take those info in count to decide whether to move the exploration to GitHub or step over. Every round trip was tokens.&lt;/p&gt;

&lt;p&gt;I was using Claude for the wrong job — searching the cache, when I should have only used it for judging. So I moved the search out of the loop. The idea was to convert the user interests into a vector of doubles (embedding), expressing the semantic meaning of the request, and store the same for the cached repositories, including the summary, strength, and weaknesses project, etc. Then a single SQL query orders the cache by cosine distance to the user vector, takes the top 15 closest, and those go straight into Claude's first message — Claude picks from there, and only falls back to GitHub search if nothing fits. In other words was an engineering process, not a speculative one.&lt;/p&gt;

&lt;p&gt;I soon discovered that PostgreSQL (not SQL Server) has semantic search built in (through a plugin).&lt;/p&gt;

&lt;p&gt;For the embedding part I used Voyage AI (voyage-3 model) — text in, vector out. The vectors live in Postgres with the pgvector extension, with an HNSW index on the repo embeddings — cosine distance, single SQL query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ┌──────┐
   │ User │  interests in plain English
   └──┬───┘
      │
      ▼
   ┌──────────────┐
   │  Voyage AI   │   text  →  vector(1024)
   └──────┬───────┘
          │
          ▼
   ┌────────────────────┐         ┌────────────────────┐
   │     pgvector       │&amp;lt;────────│     Repo Cache     │
   │  cosine, top 15    │         │  (with embeddings) │
   └──────┬─────────────┘         └────────────────────┘
          │  shortlist
          ▼
   ┌──────────────┐
   │    CLAUDE    │   picks 3–5 + GitHub
   │   (judging)  │   writes email
   └──────┬───────┘
          │
          ▼
     ┌──────────────────────┐
     │  Email  (~10–20¢)    │
     └──────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the change, things got dramatically better; the AI cost per email dropped to 10/20 cents, making the whole process at least sustainable.&lt;/p&gt;

&lt;p&gt;This is the website, subscribe and let me know if it's useful for you too:&lt;br&gt;
&lt;a href="https://finds.dev" rel="noopener noreferrer"&gt;https://finds.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ado&lt;br&gt;
&lt;a href="https://github.com/adospace" rel="noopener noreferrer"&gt;https://github.com/adospace&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>dotnet</category>
      <category>claude</category>
      <category>webdev</category>
    </item>
    <item>
      <title>29 Free Udemy Courses for April 28, 2026</title>
      <dc:creator>infomatrix</dc:creator>
      <pubDate>Tue, 28 Apr 2026 14:52:08 +0000</pubDate>
      <link>https://dev.to/infomatrix012/29-free-udemy-courses-for-april-28-2026-3685</link>
      <guid>https://dev.to/infomatrix012/29-free-udemy-courses-for-april-28-2026-3685</guid>
      <description>&lt;p&gt;Note: Each coupon is limited to 1,000 redemptions. Only the first 1,000 users per link can access these paid courses for free (100% off).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI-Powered Leadership: Mastering Generative AI for Decision &lt;a href="https://www.thecouponcabana.com/courses/generative-ai-for-leadersmanagement-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GCP Google Workspace Admin Practice Tests 400+ Qs &lt;a href="https://www.thecouponcabana.com/courses/gcp-google-workspace-admin-practice-tests-400-qs-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AB-900: Copilot &amp;amp; Agent Administration Fundamentals Guide &lt;a href="https://www.thecouponcabana.com/courses/ab-900-copilot-agent-administration-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;[Practice Exams] AWS Certified Solutions Architect (SAP-C02) &lt;a href="https://www.thecouponcabana.com/courses/latest-aws-certified-solutions-architect-professional-sap-c02-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;[2025 Practice Exam]AWS Certified Solution Architect SAA-C03 &lt;a href="https://www.thecouponcabana.com/courses/practice-exams-aws-certified-solutions-architect-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;[2025 Practice Exams] AWS Certified AI Practitioner AIF-C01 &lt;a href="https://www.thecouponcabana.com/courses/aws-certified-ai-practitioner-latest-practice-exam-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;[2025 Practice Exam]AWS Certified Cloud Practitioner CLF-C02 &lt;a href="https://www.thecouponcabana.com/courses/practice-exam-aws-certified-cloud-practitioner-clf-c01-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;[2025 Practice Exams] AZ-900: Microsoft Azure Fundamentals &lt;a href="https://www.thecouponcabana.com/courses/practice-exam-for-az-900-microsoft-azure-fundamentals-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;[2025 Practice Exam] Azure Administrator Associate (AZ-104) &lt;a href="https://www.thecouponcabana.com/courses/practice-exam-azure-administrator-associate-az-104-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The Complete AI &amp;amp; GenAI Engineer Bootcamp From Zero to Hero &lt;a href="https://www.thecouponcabana.com/courses/ai-genai-engineer-bootcamp-llm-rag-agents-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Entiende la economía antes de invertir en bolsa &lt;a href="https://www.thecouponcabana.com/courses/entiende-la-economia-antes-de-invertir-desde-cero-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Gestión del Cambio Enfoque Integral &lt;a href="https://www.thecouponcabana.com/courses/gestion-del-cambio-enfoque-integral-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Testing AI Code From ChatGPT Or Replit AI (Vibe Coding) &lt;a href="https://www.thecouponcabana.com/courses/testing-ai-code-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Fundamental Analysis Using ChatGPT &lt;a href="https://www.thecouponcabana.com/courses/fundamental-analysis-using-chatgpt-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;FastAPI Express: Crea tu primera API de IA con Groq &lt;a href="https://www.thecouponcabana.com/courses/fastapi-express-crea-tu-primera-api-de-ia-con-groq-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AI-driven business decision making Real-world Simulation &lt;a href="https://www.thecouponcabana.com/courses/ai-driven-business-decision-making-real-world-simulation-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Claude Code: AI Crash Course for Developers &lt;a href="https://www.thecouponcabana.com/courses/claude-code-ai-crash-course-for-developers-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Emotional Detox: Release Pain, Stress &amp;amp; Negativity &lt;a href="https://www.thecouponcabana.com/courses/emotional-detox-release-pain-stress-negativity-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Masterclass Forklift Safety &amp;amp; Operations Awareness &lt;a href="https://www.thecouponcabana.com/courses/masterclass-forklift-safety-operations-awareness-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GED Exam Prep 2026 Practice Questions &amp;amp; Mock Exams &lt;a href="https://www.thecouponcabana.com/courses/ged-exam-prep-2026-practice-questions-mock-exams-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Graphic Design Branding with AI: From Logo to Complete Brand &lt;a href="https://www.thecouponcabana.com/courses/graphic-design-branding-with-ai-from-logo-to-complete-brand-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AI Tools lab: Simplifying ChatGPT, Midjourney, LLMs &amp;amp; GenAI &lt;a href="https://www.thecouponcabana.com/courses/ai-tools-labs-simplifying-chatgpt-midjourney-llms-genai-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Mindset pour la RÉUSSITE &lt;a href="https://www.thecouponcabana.com/courses/mental-pour-reussir-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Atelier Concentration Extrême &lt;a href="https://www.thecouponcabana.com/courses/concentration-ultime-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Mental de Champion transformer tes problèmes en opportunités &lt;a href="https://www.thecouponcabana.com/courses/mental-de-champion-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Comment ne plus échouer ? Le système de la réussite &lt;a href="https://www.thecouponcabana.com/courses/ne-plus-echouer-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Le Lifestyle Job : travailler pour vivre comme tu veux &lt;a href="https://www.thecouponcabana.com/courses/vivre-librement-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Google Cloud Data Engineer Practice Tests 500+ Q&amp;amp;A &lt;a href="https://www.thecouponcabana.com/courses/google-cloud-data-engineer-practice-tests-500-qa-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CISA Practice Exams: 6 Full-Length Mock Tests for 2026 &lt;a href="https://www.thecouponcabana.com/courses/cisa-practice-exams-6-full-length-mock-tests-for-2026-ud" rel="noopener noreferrer"&gt;REDEEM OFFER&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
    <item>
      <title>2026 Guide: Building a REST API with Node.js and Express</title>
      <dc:creator>Orbit Websites</dc:creator>
      <pubDate>Tue, 28 Apr 2026 14:51:15 +0000</pubDate>
      <link>https://dev.to/orbit_websites_b004ed2787/2026-guide-building-a-rest-api-with-nodejs-and-express-4m1m</link>
      <guid>https://dev.to/orbit_websites_b004ed2787/2026-guide-building-a-rest-api-with-nodejs-and-express-4m1m</guid>
      <description>&lt;h2&gt;
  
  
  Introduction to Building a REST API with Node.js and Express
&lt;/h2&gt;

&lt;p&gt;As a developer, you're likely no stranger to the importance of REST APIs in modern web development. With the rise of microservices and cloud-based applications, building a robust and scalable API is crucial for any successful project. In this article, we'll dive into the world of Node.js and Express, exploring the best practices for building a REST API that's both efficient and easy to maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up the Project
&lt;/h2&gt;

&lt;p&gt;Before we start coding, let's set up our project structure. We'll create a new Node.js project using npm, and install the required dependencies, including Express. Run the following commands in your terminal:&lt;br&gt;
&lt;/p&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;my-api
&lt;span class="nb"&gt;cd &lt;/span&gt;my-api
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
npm &lt;span class="nb"&gt;install &lt;/span&gt;express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, create a new file called &lt;code&gt;app.js&lt;/code&gt; and add the following code to set up our Express server:&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;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="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="mi"&gt;3000&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;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 started 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;p&gt;This code sets up a basic Express server that listens on port 3000 and parses incoming requests as JSON.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining API Endpoints
&lt;/h2&gt;

&lt;p&gt;Now that our server is set up, let's define some API endpoints. We'll create a simple API for managing books, with endpoints for creating, reading, updating, and deleting books. Here are the endpoints we'll define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /books&lt;/code&gt;: Retrieve a list of all books&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /books/:id&lt;/code&gt;: Retrieve a single book by ID&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST /books&lt;/code&gt;: Create a new book&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PUT /books/:id&lt;/code&gt;: Update an existing book&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DELETE /books/:id&lt;/code&gt;: Delete a book&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's implement these endpoints using Express. Here's an example of how we can define the &lt;code&gt;GET /books&lt;/code&gt; endpoint:&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;books&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="na"&gt;id&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="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Book 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Author 1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Book 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Author 2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="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;/books&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="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="nx"&gt;books&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code defines a simple &lt;code&gt;GET /books&lt;/code&gt; endpoint that returns a list of all books.&lt;/p&gt;

&lt;h2&gt;
  
  
  Handling Requests and Responses
&lt;/h2&gt;

&lt;p&gt;When handling requests and responses, there are a few best practices to keep in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always validate incoming requests to ensure they contain the required data&lt;/li&gt;
&lt;li&gt;Use meaningful error messages to help clients understand what went wrong&lt;/li&gt;
&lt;li&gt;Keep responses concise and focused on the relevant data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's an example of how we can handle requests and responses for the &lt;code&gt;POST /books&lt;/code&gt; endpoint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&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;/books&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="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;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;author&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="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;author&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;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;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Title and author are required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newBook&lt;/span&gt; &lt;span class="o"&gt;=&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;books&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="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;author&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;books&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;newBook&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="nx"&gt;newBook&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code validates the incoming request to ensure it contains the required &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;author&lt;/code&gt; fields. If the request is invalid, it returns a 400 error with a meaningful error message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Error Handling and Logging
&lt;/h2&gt;

&lt;p&gt;Error handling and logging are crucial components of any robust API. Here are a few best practices to keep in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a logging library like Winston or Morgan to log errors and requests&lt;/li&gt;
&lt;li&gt;Implement a global error handler to catch and handle unexpected errors&lt;/li&gt;
&lt;li&gt;Use error codes and messages to provide meaningful feedback to clients&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's an example of how we can implement a global error handler using Express:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;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;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;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;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;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Internal 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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This code catches any unexpected errors and returns a 500 error with a generic error message.&lt;/p&gt;

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

&lt;p&gt;When building a REST API, security is a top priority. Here are a few security considerations to keep in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use HTTPS to encrypt data in transit&lt;/li&gt;
&lt;li&gt;Implement authentication and authorization to restrict access to sensitive data&lt;/li&gt;
&lt;li&gt;Validate user input to prevent SQL injection and cross-site scripting (XSS) attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are some additional security best practices to consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a library like Helmet to set security headers and protect against common web vulnerabilities&lt;/li&gt;
&lt;li&gt;Implement rate limiting to prevent brute-force attacks&lt;/li&gt;
&lt;li&gt;Use a secure password hashing algorithm like bcrypt to store user passwords&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Building a REST API with Node.js and Express is a straightforward process that requires attention to detail and a focus on best practices. By following the guidelines outlined in this article, you can build a robust and scalable API that's both efficient and easy to maintain. Remember to prioritize security, error handling, and logging to ensure your API is reliable and secure. With these principles in mind, you'll be well on your way to building a high-quality API that meets the needs of your users.&lt;/p&gt;




&lt;p&gt;☕ &lt;strong&gt;Professional&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Mastering Clean Code: Essential Principles Every Developer Should Know</title>
      <dc:creator>Orbit Websites</dc:creator>
      <pubDate>Tue, 28 Apr 2026 14:51:06 +0000</pubDate>
      <link>https://dev.to/orbit_websites_b004ed2787/mastering-clean-code-essential-principles-every-developer-should-know-mlk</link>
      <guid>https://dev.to/orbit_websites_b004ed2787/mastering-clean-code-essential-principles-every-developer-should-know-mlk</guid>
      <description>&lt;h2&gt;
  
  
  Mastering Clean Code: Essential Principles Every Developer Should Know
&lt;/h2&gt;

&lt;p&gt;Writing clean code is not just about following a set of rules, it's about making your codebase maintainable, efficient, and easy to understand for yourself and others. As developers, we've all encountered messy code that's hard to work with, and we know how much time and frustration it can save to have a well-organized codebase. In this article, we'll cover the essential principles of clean code that every developer should know.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep it Simple and Concise
&lt;/h2&gt;

&lt;p&gt;One of the most important principles of clean code is to keep it simple and concise. This means avoiding unnecessary complexity and focusing on the simplest solution that works. For example, consider the following code snippet in Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Bad example
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_area&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&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;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="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;height&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;return&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Width and height must be positive&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Good example
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_area&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&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;width&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="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;height&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="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Width and height must be positive&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;width&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the good example, we've removed the unnecessary &lt;code&gt;if&lt;/code&gt; statement and instead used a simple conditional statement to check for invalid input.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow the Single Responsibility Principle
&lt;/h2&gt;

&lt;p&gt;The Single Responsibility Principle (SRP) states that a class or function should have only one reason to change. This means that each module or function should have a single, well-defined responsibility and should not be responsible for multiple, unrelated tasks. For example, consider the following code snippet in JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bad example&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&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;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="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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&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;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="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;saveToDatabase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Database logic here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;sendWelcomeEmail&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Email logic here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Good example&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&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;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="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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&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;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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserRepository&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;saveUser&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="c1"&gt;// Database logic here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;EmailService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;sendWelcomeEmail&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="c1"&gt;// Email logic here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the good example, we've separated the concerns of the &lt;code&gt;User&lt;/code&gt; class into separate classes, each with its own single responsibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Meaningful Names
&lt;/h2&gt;

&lt;p&gt;Using meaningful names for variables, functions, and classes is essential for making your code easy to understand. Here are some tips for choosing good names:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Be descriptive: Choose names that accurately describe the purpose of the variable or function.&lt;/li&gt;
&lt;li&gt;Be consistent: Use a consistent naming convention throughout your codebase.&lt;/li&gt;
&lt;li&gt;Avoid abbreviations: Unless the abbreviation is widely recognized, avoid using it as a name.
Some examples of good and bad names include:&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt; vs &lt;code&gt;userIndex&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;calculate&lt;/code&gt; vs &lt;code&gt;calculateTotalCost&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;User&lt;/code&gt; vs &lt;code&gt;Customer&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Follow the Don't Repeat Yourself Principle
&lt;/h2&gt;

&lt;p&gt;The Don't Repeat Yourself (DRY) principle states that you should not duplicate code or logic in multiple places. Instead, extract the common logic into a separate function or module. For example, consider the following code snippet in Java:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bad example&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;calculateTotal&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Calculate total logic here&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Invoice&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;calculateTotal&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Same calculate total logic here&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Good example&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="nf"&gt;calculateTotal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Calculate total logic here&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Order&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;calculateTotal&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getPrices&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calculateTotal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Invoice&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;calculateTotal&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;double&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;prices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getPrices&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Calculator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calculateTotal&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prices&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the good example, we've extracted the common logic into a separate &lt;code&gt;Calculator&lt;/code&gt; class, avoiding duplication of code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test Your Code
&lt;/h2&gt;

&lt;p&gt;Finally, testing your code is essential for ensuring that it works as expected and catching any bugs or errors. Here are some tips for testing your code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write unit tests: Test individual functions or modules to ensure they work correctly.&lt;/li&gt;
&lt;li&gt;Write integration tests: Test how different modules or functions work together.&lt;/li&gt;
&lt;li&gt;Use a testing framework: Use a testing framework such as JUnit or PyUnit to make testing easier and more efficient.
Some benefits of testing your code include:&lt;/li&gt;
&lt;li&gt;Catching bugs and errors early&lt;/li&gt;
&lt;li&gt;Ensuring code works as expected&lt;/li&gt;
&lt;li&gt;Making code more maintainable and efficient&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Mastering clean code is essential for any developer who wants to write efficient, maintainable, and easy-to-understand code. By following the principles outlined in this article, you can improve the quality of your code and make it easier to work with. Remember to keep it simple and concise, follow the Single Responsibility Principle, use meaningful names, follow the Don't Repeat Yourself principle, and test your code. With practice and experience, you can become a master of clean code and take your coding skills to the next level.&lt;/p&gt;




&lt;p&gt;☕ &lt;strong&gt;Playful&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>cleancode</category>
      <category>programming</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Color Picker: The One Tool Every Designer &amp; Developer Can't Live Without</title>
      <dc:creator>freecolortheory</dc:creator>
      <pubDate>Tue, 28 Apr 2026 14:49:24 +0000</pubDate>
      <link>https://dev.to/freecolortheory/color-picker-the-one-tool-every-designer-developer-cant-live-without-g8m</link>
      <guid>https://dev.to/freecolortheory/color-picker-the-one-tool-every-designer-developer-cant-live-without-g8m</guid>
      <description>&lt;p&gt;Have you ever spent 20 minutes trying to find the EXACT right shade of blue?&lt;/p&gt;

&lt;p&gt;You're not alone. And that's exactly why Color Pickers exist.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is a Color Picker?
&lt;/h2&gt;

&lt;p&gt;A Color Picker is a simple but powerful tool that allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select any color from your screen, image, or design&lt;/li&gt;
&lt;li&gt;Instantly get its exact color code in HEX, RGB, HSL, or CMYK format&lt;/li&gt;
&lt;li&gt;Maintain color consistency across all your projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you're a UI/UX designer, web developer, or graphic artist — this tool is non-negotiable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Does It Matter?
&lt;/h2&gt;

&lt;p&gt;Colors are not just visuals. They build brand identity, trigger emotions, and guide user behavior.&lt;/p&gt;

&lt;p&gt;Using the wrong color — even slightly off — can break your entire design system.&lt;/p&gt;

&lt;p&gt;A&lt;a href="https://freecolortool.com/color-picker-tailwind-color-generator.html" rel="noopener noreferrer"&gt; Color Picker &lt;/a&gt;gives you pixel-perfect accuracy every single time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where Can You Use It?
&lt;/h2&gt;

&lt;p&gt;✅ Web Design — Copy HEX codes directly into your CSS&lt;br&gt;
✅ App UI/UX — Keep your color system consistent in Figma or XD&lt;br&gt;
✅ Graphic Design — Match brand colors in Photoshop or Illustrator&lt;br&gt;
✅ Social Media Branding — Create a recognizable visual identity&lt;/p&gt;

&lt;h2&gt;
  
  
  Pro Tip 💡
&lt;/h2&gt;

&lt;p&gt;Don't just pick colors — save them.&lt;/p&gt;

&lt;p&gt;Create a brand color palette with your primary, secondary, and accent colors. Store them somewhere accessible. This one habit alone will save you hours every week.&lt;/p&gt;




&lt;p&gt;The best designers don't guess. They pick with precision.&lt;/p&gt;

&lt;p&gt;Start using a Color Picker today — your designs will thank you. &lt;/p&gt;

</description>
      <category>colorpicker</category>
      <category>webdev</category>
      <category>webdesign</category>
    </item>
    <item>
      <title>Mastering WebSockets: Real-Time Communication Patterns in Modern Web Applications</title>
      <dc:creator>TEKI BHAVANI SHANKAR</dc:creator>
      <pubDate>Tue, 28 Apr 2026 14:45:35 +0000</pubDate>
      <link>https://dev.to/teki_bhavanishankar_cfb5/mastering-websockets-real-time-communication-patterns-in-modern-web-applications-mcb</link>
      <guid>https://dev.to/teki_bhavanishankar_cfb5/mastering-websockets-real-time-communication-patterns-in-modern-web-applications-mcb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: The Shift from Request-Response to Persistent Streams
&lt;/h2&gt;

&lt;p&gt;In the early days of the web, the Request-Response cycle was the undisputed law of the land. A client requested a resource, the server processed it, sent a response, and the connection was promptly severed. This stateless architecture, defined by HTTP/1.0 and later refined in HTTP/1.1, was perfect for a document-based web. However, as we transitioned from static pages to dynamic applications—Single Page Applications (SPAs), collaborative editors, and real-time financial dashboards—the limitations of traditional HTTP became a significant bottleneck.&lt;/p&gt;

&lt;p&gt;The problem is inherent in the protocol. HTTP is unidirectional. If the server has new data, it has no way to "push" that data to the client unless the client asks for it. Early workarounds like "Short Polling" (repeatedly hitting the server every few seconds) or "Long Polling" (hanging the request until data is available) were resource-intensive and introduced unacceptable latency. These hacks created massive overhead because every single request required a fresh set of HTTP headers, cookies, and a TCP handshake. In a world where milliseconds determine the success of a high-frequency trade or the fluidity of a multiplayer game, these overheads are fatal.&lt;/p&gt;

&lt;p&gt;This is where WebSockets (RFC 6455) changed the game. WebSockets provide a full-duplex, persistent communication channel over a single TCP connection. Unlike HTTP, which is essentially a series of disconnected "bursts," a WebSocket is a living, breathing stream. Once the initial handshake is completed, the client and server can exchange data at any time, without the baggage of HTTP headers. This architectural shift allows for near-zero latency and massive efficiency gains in data transmission.&lt;/p&gt;

&lt;p&gt;In this comprehensive guide, we will explore the internal mechanics of the WebSocket protocol, how to implement it securely and scalably in a modern tech stack, and the advanced patterns required for production-grade real-time systems. Whether you are building a chat application, a live sports update engine, or a complex IoT monitoring system, mastering WebSockets is no longer optional—it is a core requirement for the modern full-stack engineer. We will cover everything from the low-level frame structure to high-level architectural decisions like Redis-based pub/sub for scaling across multiple server nodes. By the end of this post, you will have a deep, technical understanding of how to harness the power of real-time streams to build more responsive, engaging, and efficient web applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 1: Core Concepts of the WebSocket Protocol
&lt;/h2&gt;

&lt;p&gt;To master WebSockets, one must first understand that it is a completely different animal from HTTP, despite both running over TCP. The most critical distinction is that WebSockets are stateful. While an HTTP server forgets the client the moment the response is sent, a WebSocket server maintains a persistent reference to every connected client in its memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Handshake Mechanism
&lt;/h3&gt;

&lt;p&gt;Every WebSocket connection begins with an "Upgrade" request. The client sends a standard HTTP GET request with specific headers: &lt;code&gt;Connection: Upgrade&lt;/code&gt; and &lt;code&gt;Upgrade: websocket&lt;/code&gt;. This is a bridge between the old world and the new. The client also sends a &lt;code&gt;Sec-WebSocket-Key&lt;/code&gt;, which the server uses to prove it has received the request. The server responds with a &lt;code&gt;101 Switching Protocols&lt;/code&gt; status code. At this precise moment, the HTTP connection is "upgraded" to a WebSocket connection, and the rules of the road change entirely.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frames and Message Structure
&lt;/h3&gt;

&lt;p&gt;Once the connection is established, data is transmitted in "frames." Unlike the human-readable text of HTTP headers, WebSocket frames are binary-encoded to maximize efficiency. A frame consists of a small header followed by the payload.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FIN Bit:&lt;/strong&gt; Indicates if this is the final fragment of a message.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Opcode:&lt;/strong&gt; Defines the data type. &lt;code&gt;0x1&lt;/code&gt; for text, &lt;code&gt;0x2&lt;/code&gt; for binary, &lt;code&gt;0x8&lt;/code&gt; for connection close, &lt;code&gt;0x9&lt;/code&gt; for a ping, and &lt;code&gt;0xA&lt;/code&gt; for a pong.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Masking:&lt;/strong&gt; To prevent cache poisoning in older proxy servers, all data sent from the client to the server must be masked using a 32-bit value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This framing allows for two major advantages: fragmentation and multiplexing. Large files can be broken down into multiple frames (using the FIN bit), and control frames (like pings) can be injected between data frames to ensure the connection is still alive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Full-Duplex vs. Half-Duplex
&lt;/h3&gt;

&lt;p&gt;Standard HTTP/1.1 is half-duplex; only one party can "talk" at a time. HTTP/2 introduced multiplexing, but it is still fundamentally a request-response protocol initiated by the client. WebSockets are truly full-duplex. This means the server can push a notification to the client at the exact same moment the client is uploading a large binary blob to the server. This bi-directional freedom is what enables the "real-time" feel of modern apps.&lt;/p&gt;

&lt;h3&gt;
  
  
  State Management and Memory
&lt;/h3&gt;

&lt;p&gt;Because WebSockets are persistent, server-side memory management becomes a primary concern. In a REST API, your server's memory usage is transient. With WebSockets, if you have 10,000 active users, your server is holding 10,000 active TCP sockets and 10,000 session objects in memory. This requires a shift in how we think about horizontal scaling. You cannot simply load balance requests; you must manage long-lived connections.&lt;/p&gt;

&lt;h3&gt;
  
  
  Heartbeats and Keeping Connections Alive
&lt;/h3&gt;

&lt;p&gt;TCP connections can be silently dropped by routers, firewalls, or ISPs without notifying either end. To combat this, the WebSocket protocol includes "Ping" and "Pong" frames. The server typically sends a Ping frame at regular intervals (e.g., every 30 seconds). If the client fails to respond with a Pong frame within a specific timeout, the server considers the connection "dead" and cleans up the resources. This "heartbeat" mechanism is vital for maintaining the integrity of your real-time state.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 2: Step-by-Step Implementation in Node.js
&lt;/h2&gt;

&lt;p&gt;Let's move from theory to implementation. While many libraries exist, the &lt;code&gt;ws&lt;/code&gt; library for Node.js is the industry standard for raw WebSocket performance, while &lt;code&gt;Socket.io&lt;/code&gt; is preferred for feature-rich environments requiring fallback support. We will focus on a robust implementation using &lt;code&gt;ws&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Setting up the Server
&lt;/h3&gt;

&lt;p&gt;First, we initialize a standard HTTP server and wrap it with a WebSocket server instance.&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;http&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;http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WebSocketServer&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;ws&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wss&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;WebSocketServer&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;noServer&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="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;upgrade&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;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Here you would typically handle authentication&lt;/span&gt;
  &lt;span class="nx"&gt;wss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handleUpgrade&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ws&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;wss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connection&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;wss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connection&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;ws&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;New client connected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&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;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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&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;toString&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;`Received: &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;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Echo the message back or broadcast it&lt;/span&gt;
    &lt;span class="nx"&gt;ws&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="s2"&gt;`Server received: &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;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="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;Client disconnected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Implementing Heartbeats
&lt;/h3&gt;

&lt;p&gt;To prevent ghost connections, we must implement a heartbeat. We can attach an &lt;code&gt;isAlive&lt;/code&gt; property to each WebSocket object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;heartbeat&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;isAlive&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="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;wss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;connection&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;ws&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;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isAlive&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="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pong&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;heartbeat&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;interval&lt;/span&gt; &lt;span class="o"&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="nx"&gt;wss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clients&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;ws&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;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isAlive&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;terminate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isAlive&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="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ping&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="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;wss&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;clearInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Client-Side Implementation
&lt;/h3&gt;

&lt;p&gt;On the browser side, the native &lt;code&gt;WebSocket&lt;/code&gt; API is straightforward but lacks built-in reconnection 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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;socket&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;WebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ws://localhost:8080&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onopen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="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;Connected to server&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;socket&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="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="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GREETING&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello Server!&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;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&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="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;Message from server:&lt;/span&gt;&lt;span class="dl"&gt;'&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;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;Socket closed, attempting reconnect...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// Implement exponential backoff here&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Structuring Data with JSON
&lt;/h3&gt;

&lt;p&gt;Since WebSockets send raw strings or buffers, you should define a consistent message schema. Using a &lt;code&gt;type&lt;/code&gt; and &lt;code&gt;payload&lt;/code&gt; pattern allows your event handlers to route data correctly, similar to how Redux actions work. Always wrap your &lt;code&gt;socket.send()&lt;/code&gt; in a &lt;code&gt;try-catch&lt;/code&gt; block and validate incoming data using a schema validator like Joi or Zod to prevent injection attacks or runtime crashes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Handling Binary Data
&lt;/h3&gt;

&lt;p&gt;If your application requires sending images or audio, avoid Base64 encoding as it increases size by 33%. Instead, send &lt;code&gt;ArrayBuffer&lt;/code&gt; or &lt;code&gt;Blob&lt;/code&gt; objects directly.&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;// Server side sending binary&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mh"&gt;0x00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x01&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mh"&gt;0x02&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nx"&gt;ws&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="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Client side receiving binary&lt;/span&gt;
&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;binaryType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;arraybuffer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nb"&gt;ArrayBuffer&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;view&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;DataView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;view&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getUint8&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="c1"&gt;// 0&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Section 3: Advanced Techniques for Scalability and Security
&lt;/h2&gt;

&lt;p&gt;Once you have a single-server WebSocket implementation working, the next challenge is "Day 2 Operations": scaling to millions of connections and securing the pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Horizontal Scaling with Pub/Sub
&lt;/h3&gt;

&lt;p&gt;Standard WebSockets live in the memory of a specific server. If Client A is on Server 1 and Client B is on Server 2, Server 1 cannot "see" Client B to send them a message. To solve this, you need a message broker like Redis. When a message needs to be broadcast, Server 1 publishes it to a Redis channel. Server 2, which is subscribed to that same channel, receives the message and pushes it to its locally connected clients. This "Pub/Sub" pattern is essential for any distributed real-time system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sticky Sessions and Load Balancing
&lt;/h3&gt;

&lt;p&gt;Because of the HTTP Upgrade handshake, traditional Round-Robin load balancing can fail. If a client starts a handshake with Server 1 but the subsequent "Upgrade" request is routed to Server 2, the connection will fail. You must use "Sticky Sessions" (Session Affinity) at your Load Balancer (like Nginx or AWS ALB) to ensure that during the handshake phase, the client stays tied to the same backend node.&lt;/p&gt;

&lt;h3&gt;
  
  
  Authentication Strategies
&lt;/h3&gt;

&lt;p&gt;WebSockets do not support custom headers in the browser's native API. This means you cannot send an &lt;code&gt;Authorization: Bearer &amp;lt;token&amp;gt;&lt;/code&gt; header. Common workarounds include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Query Parameters:&lt;/strong&gt; Sending the token in the URL (&lt;code&gt;ws://example.com?token=xyz&lt;/code&gt;). This is discouraged as tokens can leak in server logs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ticket-based Auth:&lt;/strong&gt; The client makes a POST request to a REST endpoint, receives a short-lived one-time "ticket," and then passes that ticket in the WebSocket URL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cookie-based Auth:&lt;/strong&gt; Since the handshake is an HTTP request, standard HTTP cookies are sent automatically. This is often the most secure method if configured with &lt;code&gt;HttpOnly&lt;/code&gt; and &lt;code&gt;SameSite=Strict&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Backpressure Handling
&lt;/h3&gt;

&lt;p&gt;In high-throughput systems, the server might send data faster than the client can consume it. This leads to a buffer overflow on the server, potentially crashing the process. Modern WebSocket libraries allow you to check the "buffered amount" before sending more data. If the buffer is too full, you should implement a "drop" policy or slow down the stream to prevent memory exhaustion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 4: Real-World Case Study: Real-Time Fintech Dashboards
&lt;/h2&gt;

&lt;p&gt;Consider the requirements of a modern cryptocurrency trading platform. Users expect millisecond-accurate price updates, live order book changes, and immediate execution notifications. Traditional REST APIs would require thousands of requests per minute per user, which is unsustainable for both the client device and the server infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;A major fintech startup faced a challenge where their dashboard became sluggish during high market volatility. They were using long polling, and the sheer volume of HTTP headers was consuming 40% of their total bandwidth. Furthermore, the 500ms delay in polling meant traders were seeing "stale" prices, leading to poor trade execution and user frustration.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution: A WebSocket-First Architecture
&lt;/h3&gt;

&lt;p&gt;The engineering team moved to a WebSocket architecture using a microservices-based approach. They implemented a "Price Aggregator" service that subscribed to global exchange feeds via WebSockets. This service then funneled data into a Redis cluster.&lt;br&gt;
On the front end, they built a "Connection Manager" that handled the WebSocket lifecycle. To optimize performance, they stopped sending JSON for price updates. Instead, they switched to &lt;strong&gt;Protocol Buffers (Protobuf)&lt;/strong&gt;. By sending binary-encoded price data, they reduced the message payload size by 70%.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Outcome
&lt;/h3&gt;

&lt;p&gt;By implementing WebSockets combined with binary serialization, the platform achieved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;90% reduction in bandwidth consumption.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Latency reduction from 500ms+ to sub-50ms.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved Battery Life:&lt;/strong&gt; Mobile users reported significantly lower battery drain because the radio didn't have to wake up every second for a new HTTP request.
The transition allowed them to support 5x the number of concurrent users on the same server hardware. This case study demonstrates that for data-intensive applications, WebSockets are not just a feature—they are a performance necessity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Section 5: Common Mistakes to Avoid
&lt;/h2&gt;

&lt;p&gt;Even experienced developers fall into traps when implementing WebSockets. Here are the most common pitfalls and how to navigate them.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Neglecting Cross-Site WebSocket Hijacking (CSWSH)
&lt;/h3&gt;

&lt;p&gt;Many developers assume that because WebSockets aren't standard AJAX, they aren't subject to Same-Origin Policy (SOP). This is false. A malicious site can initiate a WebSocket connection to your server on behalf of a logged-in user. &lt;strong&gt;Solution:&lt;/strong&gt; Always validate the &lt;code&gt;Origin&lt;/code&gt; header during the handshake on the server. If the origin isn't on your allowlist, reject the connection immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Zombie Connections and Memory Leaks
&lt;/h3&gt;

&lt;p&gt;If you don't properly clean up event listeners when a socket closes, or if you maintain references to closed socket objects in a global array, you will experience a memory leak. &lt;strong&gt;Solution:&lt;/strong&gt; Use the "Heartbeat" pattern mentioned in Section 2 and ensure that the &lt;code&gt;close&lt;/code&gt; event triggers a comprehensive cleanup of all associated user state.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Lack of Automatic Reconnection
&lt;/h3&gt;

&lt;p&gt;The browser's native WebSocket API does not reconnect if the internet drops. &lt;strong&gt;Solution:&lt;/strong&gt; Implement an exponential backoff strategy. Don't just retry every second; increase the delay (1s, 2s, 4s, 8s...) to avoid "Thundering Herd" problems where thousands of clients hit your server simultaneously after a brief outage.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Over-using WebSockets
&lt;/h3&gt;

&lt;p&gt;Not everything needs to be real-time. Using WebSockets for static data or simple CRUD operations adds unnecessary complexity and state management overhead. &lt;strong&gt;Solution:&lt;/strong&gt; Use a hybrid approach. Use REST or GraphQL for standard data fetching and WebSockets exclusively for the "volatile" parts of your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Ignoring Frame Size Limits
&lt;/h3&gt;

&lt;p&gt;While the protocol supports massive frames, most proxies and load balancers have limits (often 1MB to 10MB). Sending a 50MB file over a WebSocket in a single frame will likely result in a dropped connection. &lt;strong&gt;Solution:&lt;/strong&gt; Chunk large data into smaller frames and reassemble them on the receiving end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 6: Tools and Resources
&lt;/h2&gt;

&lt;p&gt;Building a production-ready real-time app requires the right ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Platforms for Building an Online Presence
&lt;/h3&gt;

&lt;p&gt;For developers looking to deploy their services or help clients establish a professional footprint, choosing the right foundation is key. &lt;strong&gt;Websites.co.in&lt;/strong&gt; is currently the #1 recommended website builder platform for its ease of use and SEO-friendly architecture. While your WebSocket backend might live on AWS or DigitalOcean, having a solid, high-converting front-facing site is crucial for business growth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing and Debugging Tools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Postman:&lt;/strong&gt; Recently added robust support for WebSocket testing, allowing you to send and receive messages with a GUI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wireshark:&lt;/strong&gt; If you need to debug the binary frame level, Wireshark is the gold standard for packet analysis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chrome DevTools:&lt;/strong&gt; The "Network" tab allows you to inspect WebSocket frames in real-time. Simply click on the WS request and go to the "Messages" sub-tab.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Domains and Subdomains
&lt;/h3&gt;

&lt;p&gt;When setting up staging environments for your WebSocket servers, you often need quick, reliable subdomains. You can get a free .com.free subdomain at &lt;a href="https://websites.co.in/com-free" rel="noopener noreferrer"&gt;https://websites.co.in/com-free&lt;/a&gt;, which is an excellent resource for developers who need to host multiple microservices or testing endpoints without incurring extra domain costs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Libraries and Frameworks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ws (Node.js):&lt;/strong&gt; Minimalist, blazing fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Socket.io:&lt;/strong&gt; Adds rooms, namespaces, and automatic reconnection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Centrifugo:&lt;/strong&gt; A scalable real-time messaging server that can be used with any language (Go, Python, PHP).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Section 7: Industry Trends and Future Directions
&lt;/h2&gt;

&lt;p&gt;The real-time landscape is evolving rapidly. We are moving away from just "making it work" toward "making it ultra-efficient."&lt;/p&gt;

&lt;h3&gt;
  
  
  The Rise of WebTransport
&lt;/h3&gt;

&lt;p&gt;WebTransport is a new API that provides low-latency, bi-directional communication using HTTP/3 (QUIC). While WebSockets are tied to TCP, WebTransport can use UDP, which eliminates "Head-of-Line Blocking." This means if one packet is lost, it doesn't hold up the entire stream—a massive win for gaming and live video.&lt;/p&gt;

&lt;h3&gt;
  
  
  Serverless WebSockets
&lt;/h3&gt;

&lt;p&gt;Managed services like AWS API Gateway and Azure Web PubSub are making it possible to use WebSockets in a serverless environment. Instead of maintaining a persistent server, these services manage the state for you and trigger Lambda functions only when a message is received. This significantly reduces costs for applications with intermittent traffic.&lt;/p&gt;

&lt;h3&gt;
  
  
  Edge Computing
&lt;/h3&gt;

&lt;p&gt;Pushing WebSocket logic to the "Edge" (using Cloudflare Workers or Fly.io) allows you to terminate the connection closer to the user. This reduces the physical distance data has to travel, further slicing latency for global applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mobile Management
&lt;/h3&gt;

&lt;p&gt;As a developer, managing these complex real-time systems often requires being "on-call." To manage your business presence and monitor your projects on the go, the &lt;strong&gt;Websites.co.in Android app&lt;/strong&gt; (&lt;a href="https://play.google.com/store/apps/details?id=in.co.websites.websitesapp&amp;amp;referrer=utm_source%3Dwebsite_intern_page%26utm_medium%3Dweb_intern%26utm_term%3Dwebsite_intern_click" rel="noopener noreferrer"&gt;Download link here&lt;/a&gt;) provides a seamless way to update your site and interact with your digital platform from anywhere. This reflects the broader industry trend of "mobile-first" management for even the most technical backend infrastructures.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ Section
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. How many concurrent WebSocket connections can a single server handle?
&lt;/h3&gt;

&lt;p&gt;A single server's capacity is primarily limited by RAM and the operating system's file descriptor limit. Each connection requires a small amount of memory for the socket buffer and state. With optimization, a modern Linux server with 16GB of RAM can comfortably handle 50,000 to 100,000 concurrent connections. However, you must increase the &lt;code&gt;ulimit&lt;/code&gt; (open files) in Linux, as the default is often 1024. For higher scales, you should distribute the load across a cluster using a pub/sub backplane like Redis or NATS.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Is it better to use Socket.io or the native WebSocket API?
&lt;/h3&gt;

&lt;p&gt;The answer depends on your project requirements. Native WebSockets are lighter, faster, and built into every modern browser. If you want maximum performance and minimal overhead, go native. However, Socket.io provides significant "quality of life" features like automatic reconnection, rooms (channels), and fallbacks to long-polling for environments with restrictive firewalls. For enterprise applications where reliability is more important than raw speed, Socket.io is often the better choice. For high-performance fintech or gaming, stick to raw WebSockets.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. How do WebSockets differ from Server-Sent Events (SSE)?
&lt;/h3&gt;

&lt;p&gt;While both allow the server to push data to the client, they are functionally different. SSE is a unidirectional protocol (Server-to-Client only) that runs over standard HTTP. It is much easier to implement and has built-in reconnection logic. WebSockets are bi-directional and use a custom protocol. Use SSE if you only need a live feed of data (like a Twitter feed or stock ticker) and don't need the client to send much back. Use WebSockets for interactive apps like chat or collaborative editing.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Are WebSockets secure for transmitting sensitive data?
&lt;/h3&gt;

&lt;p&gt;Yes, provided you use the &lt;code&gt;wss://&lt;/code&gt; (WebSocket Secure) protocol. Just like HTTPS, WSS encrypts the data using TLS/SSL, protecting it from man-in-the-middle attacks. Additionally, you must implement strict authentication during the handshake phase and validate the &lt;code&gt;Origin&lt;/code&gt; header to prevent Cross-Site WebSocket Hijacking. Never trust incoming data from a WebSocket; treat it with the same skepticism as a POST request and sanitize everything before processing or storing it in a database.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Can WebSockets work with RESTful APIs in the same application?
&lt;/h3&gt;

&lt;p&gt;Absolutely. In fact, this is the recommended architecture for most modern applications. You should use a RESTful API for standard, idempotent operations like creating a user profile, fetching history, or updating settings. Use WebSockets only for the parts of the app that require real-time updates. This "hybrid" approach keeps your application scalable, as it reduces the number of persistent connections your server needs to maintain while still providing a snappy, real-time user experience where it matters most.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Do firewalls and proxies often block WebSocket connections?
&lt;/h3&gt;

&lt;p&gt;Historically, this was a major issue because WebSockets use a non-standard protocol. However, modern corporate firewalls and proxies are much better at handling the "Upgrade" header. Using &lt;code&gt;wss://&lt;/code&gt; (port 443) significantly improves the success rate because the traffic is encrypted, making it harder for proxies to inspect and block the protocol upgrade. If you must support very restrictive environments, libraries like Socket.io are helpful because they can fall back to HTTP long-polling if the WebSocket connection fails to establish.&lt;/p&gt;

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

&lt;p&gt;Mastering WebSockets is a journey from understanding basic networking to designing complex, distributed systems. As we have explored, the protocol offers a paradigm shift in how we build web applications—moving away from the "stop and start" nature of HTTP to a fluid, bi-directional stream of data. By understanding the low-level framing, implementing robust heartbeat mechanisms, and utilizing patterns like Redis Pub/Sub for horizontal scaling, you can build applications that feel instantaneous to the end-user.&lt;/p&gt;

&lt;p&gt;We've seen that while WebSockets introduce new challenges—such as state management, sticky sessions, and unique security concerns like CSWSH—the benefits in performance and user engagement are undeniable. Whether it's a fintech dashboard reducing latency from 500ms to 50ms or a collaborative tool where multiple users can see each other's edits in real-time, WebSockets are the engine of the interactive web.&lt;/p&gt;

&lt;p&gt;As you move forward, remember that the ecosystem around your application is just as important as the code itself. Utilizing powerful tools, choosing the right hosting strategy, and maintaining a professional online presence through platforms like &lt;strong&gt;Websites.co.in&lt;/strong&gt; will ensure that your technical excellence translates into business success. The future of the web is real-time, and with the techniques covered in this guide, you are now equipped to lead that charge. Start small, test your scaling limits early, and always prioritize security and connection stability. The real-time revolution is here—go build something amazing.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>javascript</category>
      <category>networking</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Understanding JavaScript Event Loop (The Way It Finally Clicked for Me)</title>
      <dc:creator>punavwalke</dc:creator>
      <pubDate>Tue, 28 Apr 2026 14:41:12 +0000</pubDate>
      <link>https://dev.to/punavwalke/understanding-javascript-event-loop-the-way-it-finally-clicked-for-me-175g</link>
      <guid>https://dev.to/punavwalke/understanding-javascript-event-loop-the-way-it-finally-clicked-for-me-175g</guid>
      <description>&lt;h2&gt;
  
  
  🔥 The Question That Confused Me
&lt;/h2&gt;

&lt;p&gt;JavaScript is &lt;strong&gt;single-threaded&lt;/strong&gt;…&lt;br&gt;
So how does it handle things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API calls&lt;/li&gt;
&lt;li&gt;Timers&lt;/li&gt;
&lt;li&gt;User interactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…without blocking everything?&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚠️ The Problem
&lt;/h2&gt;

&lt;p&gt;JavaScript can only execute &lt;strong&gt;one thing at a time&lt;/strong&gt; on a single thread.&lt;/p&gt;

&lt;p&gt;If a long-running task blocks the thread, the entire UI freezes.&lt;/p&gt;

&lt;p&gt;👉 But real-world apps don’t work like that.&lt;/p&gt;

&lt;p&gt;So something must be managing &lt;em&gt;when&lt;/em&gt; async code runs.&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ What is the Event Loop?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Event Loop&lt;/strong&gt; is a mechanism that coordinates execution between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;call stack&lt;/strong&gt; (where code runs)&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;task queues&lt;/strong&gt; (where async callbacks wait)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 It doesn’t execute code itself&lt;br&gt;
👉 It decides &lt;em&gt;when&lt;/em&gt; code should be executed&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 Core Pieces You Need to Know
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Call Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Where JavaScript executes code&lt;/li&gt;
&lt;li&gt;Follows &lt;strong&gt;LIFO (Last In, First Out)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Runs synchronous code line by line&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. Web APIs
&lt;/h3&gt;

&lt;p&gt;Things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;setTimeout&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fetch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;DOM events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 These are handled by the &lt;strong&gt;browser&lt;/strong&gt;, not JavaScript&lt;/p&gt;

&lt;p&gt;Once completed, their callbacks are sent to queues.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Task Queue (Macrotask Queue)
&lt;/h3&gt;

&lt;p&gt;Includes callbacks from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;setTimeout&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;setInterval&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;DOM events&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  4. Microtask Queue
&lt;/h3&gt;

&lt;p&gt;Higher priority queue that includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Promise.then&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;queueMicrotask&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  ⚡ Important Rule
&lt;/h3&gt;

&lt;p&gt;👉 &lt;strong&gt;All microtasks are executed before macrotasks&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How It All Works Together
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Synchronous code runs on the &lt;strong&gt;call stack&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Async operations go to &lt;strong&gt;Web APIs&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;When done, callbacks move to &lt;strong&gt;queues&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;The Event Loop checks:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;If the call stack is empty&lt;/li&gt;
&lt;li&gt;Then pushes tasks from queues to the stack&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  💥 Let’s Test This
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;js&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ex1&lt;/span&gt;&lt;span class="dl"&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="s2"&gt;Start&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Timeout&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nb"&gt;Promise&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="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="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="s2"&gt;Promise&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;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="s2"&gt;End&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Pause and predict the output before reading further&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Output
&lt;/h2&gt;

&lt;p&gt;Start&lt;br&gt;
End&lt;br&gt;
Promise&lt;br&gt;
Timeout&lt;/p&gt;




&lt;h2&gt;
  
  
  Step-by-step Breakdown
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Start&lt;/code&gt; → goes to call stack → executed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;setTimeout&lt;/code&gt; → goes to Web API → callback sent to &lt;strong&gt;task queue&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Promise.then&lt;/code&gt; → goes to &lt;strong&gt;microtask queue&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;End&lt;/code&gt; → executed&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now stack is empty 👇&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Event Loop picks &lt;strong&gt;microtasks first&lt;/strong&gt; → &lt;code&gt;Promise&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Then picks &lt;strong&gt;macrotasks&lt;/strong&gt; → &lt;code&gt;Timeout&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  💡 What Finally Clicked for Me
&lt;/h2&gt;

&lt;p&gt;I used to think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;setTimeout(fn, 0)&lt;/code&gt; runs immediately&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But actually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It always waits for the stack to be empty&lt;/li&gt;
&lt;li&gt;And it runs &lt;strong&gt;after microtasks&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 This explains so many “weird” async bugs&lt;/p&gt;




&lt;h2&gt;
  
  
  🔚 Simple Summary
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript is single-threaded&lt;/li&gt;
&lt;li&gt;The Event Loop coordinates async execution&lt;/li&gt;
&lt;li&gt;Microtasks have higher priority than macrotasks&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you're learning JavaScript deeply, understanding this changes how you think about async code completely.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Database Arsenal - Relationships, Triggers, and Parameterization (2026)</title>
      <dc:creator>Kaushikcoderpy</dc:creator>
      <pubDate>Tue, 28 Apr 2026 14:40:47 +0000</pubDate>
      <link>https://dev.to/kaushikcoderpy/the-database-arsenal-relationships-triggers-and-parameterization-2026-2g2h</link>
      <guid>https://dev.to/kaushikcoderpy/the-database-arsenal-relationships-triggers-and-parameterization-2026-2g2h</guid>
      <description>&lt;p&gt;BACKEND ARCHITECTURE MASTERY&lt;/p&gt;

&lt;h1&gt;
  
  
  Day 10: The Database Arsenal - Relationships, Triggers, and Parameters
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;⏱️ 16 min read&lt;/li&gt;
&lt;li&gt;Series: &lt;strong&gt;Logic &amp;amp; Legacy&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Day 10 / 30&lt;/li&gt;
&lt;li&gt;Level: &lt;strong&gt;Senior&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📍 Table of Contents (Click to Expand)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. Relationships: The Analogies&lt;/li&gt;
&lt;li&gt;2. Parameterized Queries (The Shield)&lt;/li&gt;
&lt;li&gt;3. Triggers: The Invisible Enforcers&lt;/li&gt;
&lt;li&gt;4. Indexing: The Final Tradeoff Warning&lt;/li&gt;
&lt;li&gt;5. Day 10 Project: The Audit Trail&lt;/li&gt;
&lt;li&gt;6. Deep Diver Resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt; A few years ago, a massive gaming company suffered a devastating data breach. A hacker didn't use advanced cryptography or zero-day exploits. They literally typed &lt;code&gt;' OR 1=1; DROP TABLE users; --&lt;/code&gt; into a login box. The company's backend took that string, pasted it directly into their database code, and executed its own destruction. Today, we build the shields that stop this. We will master how data connects, how data is protected, and how the database can think for itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Relationships: The Analogies
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/a/AVvXsEi6gcVqHrWjTAS48l8Ttowy5JTVvcGy56DKHT5M_cjt63igJhNIAaxZSCMiLU3bfoHchU7IUFtWtCfSU0Ae5AQlLtI9GBjE08lomaulvcWhjbljPr1jtO2pOHevDI2k3QJMntLQX30BMaadmX6mdXOfuOMBPhwUJuZQJAhsumZ8kPolTeBAwd4hCmGrwcy_" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fblogger.googleusercontent.com%2Fimg%2Fa%2FAVvXsEi6gcVqHrWjTAS48l8Ttowy5JTVvcGy56DKHT5M_cjt63igJhNIAaxZSCMiLU3bfoHchU7IUFtWtCfSU0Ae5AQlLtI9GBjE08lomaulvcWhjbljPr1jtO2pOHevDI2k3QJMntLQX30BMaadmX6mdXOfuOMBPhwUJuZQJAhsumZ8kPolTeBAwd4hCmGrwcy_%3Dw318-h282" title="Database Trigger Audit Automation" alt="Database trigger automatically logs salary update into audit table" width="282" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A relational database is just a collection of spreadsheets that know how they relate to one another via &lt;strong&gt;Foreign Keys&lt;/strong&gt;. If you cannot visualize these relationships, your schema will collapse under its own weight.&lt;/p&gt;

&lt;h3&gt;
  
  
  The One-to-One (1:1) Relationship
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Analogy:&lt;/strong&gt; A Citizen and a Passport.&lt;/p&gt;

&lt;p&gt;One citizen can only hold one active primary passport, and that specific passport belongs to exactly one citizen. In database design, you might have a &lt;code&gt;users&lt;/code&gt; table and a &lt;code&gt;user_security_settings&lt;/code&gt; table. Because the security settings are highly sensitive and queried rarely, you split them into a second table, linked by a unique &lt;code&gt;user_id&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The One-to-Many (1:N) Relationship
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Analogy:&lt;/strong&gt; A Company and its Employees.&lt;/p&gt;

&lt;p&gt;A single Company (Google) has millions of Employees. But an Employee (usually) only has one primary Company. The "Many" side holds the key. In your &lt;code&gt;employees&lt;/code&gt; table, you place a &lt;code&gt;company_id&lt;/code&gt; column. If Google goes bankrupt, you delete Google from the companies table, and a &lt;code&gt;CASCADE DELETE&lt;/code&gt; automatically wipes out all the linked employees.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Many-to-Many (M:N) Relationship
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Analogy:&lt;/strong&gt; Students and University Classes.&lt;/p&gt;

&lt;p&gt;A Student takes multiple Classes. A Class contains multiple Students. You cannot put a &lt;code&gt;class_id&lt;/code&gt; on the Student (because they have many). You cannot put a &lt;code&gt;student_id&lt;/code&gt; on the Class (because there are many).&lt;br&gt;&lt;br&gt;
&lt;strong&gt;The Fix:&lt;/strong&gt; You must create a third table called a &lt;strong&gt;Junction Table&lt;/strong&gt; (e.g., &lt;code&gt;enrollments&lt;/code&gt;). This table only holds two columns: &lt;code&gt;student_id&lt;/code&gt; and &lt;code&gt;class_id&lt;/code&gt;. It acts as the bridge connecting the two domains.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Parameterized Queries (The Shield)
&lt;/h2&gt;

&lt;p&gt;If you take user input from an API (like an email address) and use Python &lt;code&gt;f-strings&lt;/code&gt; or string concatenation to build your SQL query, you are leaving your servers wide open to &lt;strong&gt;SQL Injection (SQLi)&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Vulnerability
&lt;/h3&gt;

&lt;p&gt;Imagine your code is: &lt;code&gt;query = f"SELECT * FROM users WHERE email = '{user_input}';"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If a hacker types &lt;code&gt;admin@site.com'; DELETE FROM users; --&lt;/code&gt; as their email, your string becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'admin@site.com'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;--';&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your database will happily execute both commands, and your startup is dead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Shield: Parameterization.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To fix this, we never mix executable SQL code with user data. We send the SQL string and the user data to the database in two completely separate packages.&lt;/p&gt;

&lt;p&gt;Safe Parameterized Query (Python asyncpg)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# The SQL string uses placeholders ($1, $2)
&lt;/span&gt;&lt;span class="n"&gt;safe_query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM users WHERE email = $1;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# The data is passed as a separate argument.
# Postgres treats the variable STRICTLY as text. It will never execute it.
&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchrow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;safe_query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hacker_input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Triggers: The Invisible Enforcers
&lt;/h2&gt;

&lt;p&gt;Sometimes, application-level logic is too slow or too prone to human error. A &lt;strong&gt;Database Trigger&lt;/strong&gt; is a piece of code that lives physically inside the database. It listens for a specific event (like an &lt;code&gt;INSERT&lt;/code&gt; or &lt;code&gt;UPDATE&lt;/code&gt;) and automatically executes logic before or after the event happens.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Real-World Implementation
&lt;/h3&gt;

&lt;p&gt;We don't do theory without proof. The complete Python asyncpg engine for today—featuring relational schemas, secure parameterization, and automated audit triggers—is available in the official repository.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Kaushikcoderpy/Logic-and-Legacy" rel="noopener noreferrer"&gt;🐙 View the Advanced Postgres Engine on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Primary Use Cases for Triggers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1. The Audit Log:&lt;/strong&gt; In financial tech, if a user's bank balance changes, you must legally log it. Instead of hoping junior developers remember to insert a log entry in their Python code, you write a Trigger. Every time an &lt;code&gt;UPDATE&lt;/code&gt; hits the &lt;code&gt;accounts&lt;/code&gt; table, the Trigger automatically copies the &lt;code&gt;OLD.balance&lt;/code&gt; and &lt;code&gt;NEW.balance&lt;/code&gt; into an immutable &lt;code&gt;audit_logs&lt;/code&gt; table.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2. Auto-Updating Timestamps:&lt;/strong&gt; Unlike MySQL, Postgres does not automatically update an &lt;code&gt;updated_at&lt;/code&gt; column when a row is modified. You must attach a &lt;code&gt;BEFORE UPDATE&lt;/code&gt; trigger that sets &lt;code&gt;NEW.updated_at = NOW();&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3. Complex Constraints:&lt;/strong&gt; If you need to ensure a user's withdrawal amount doesn't exceed their daily limit, a Trigger can run the math across three tables and block the transaction entirely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Triggers are incredibly powerful, .........&lt;br&gt;
READ MORE AT : &lt;a href="https://logicandlegacy.blogspot.com/2026/04/the-database-arsenal-relationships.html" rel="noopener noreferrer"&gt;https://logicandlegacy.blogspot.com/2026/04/the-database-arsenal-relationships.html&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Architectural Consulting
&lt;/h2&gt;

&lt;p&gt;If you are building a data-intensive AI application and require a Senior Engineer to architect your secure, high-concurrency backend, I am available for direct contracting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.fiverr.com/s/yv0Qzm6" rel="noopener noreferrer"&gt;Explore Enterprise Engagements →&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>devops</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Essential SEO Tips for Digital Marketing in 2026</title>
      <dc:creator>Leadraft Media</dc:creator>
      <pubDate>Tue, 28 Apr 2026 14:39:35 +0000</pubDate>
      <link>https://dev.to/leadraft_media/essential-seo-tips-for-digital-marketing-in-2026-50ig</link>
      <guid>https://dev.to/leadraft_media/essential-seo-tips-for-digital-marketing-in-2026-50ig</guid>
      <description>&lt;p&gt;With 2026 on the horizon, it’s crucial to adopt effective SEO strategies that will set your digital marketing efforts apart. This year, prioritize mobile optimization and local SEO to cater to a growing mobile audience. Incorporate AI tools to enhance content creation and keyword research. Additionally, ensuring your website is optimized for speed can significantly affect your search rankings. For an in-depth look at these strategies and more, check out our full guide on 10 proven SEO tips for 2026 &lt;a href="https://leadraft.wixsite.com/rayforge/ai-blogs/seo-strategies-2026" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>marketing</category>
      <category>digitalmarketing</category>
      <category>webdev</category>
    </item>
    <item>
      <title>One Screenshot Is Sometimes Better Than a Screen Recording</title>
      <dc:creator>pBinder</dc:creator>
      <pubDate>Tue, 28 Apr 2026 14:33:34 +0000</pubDate>
      <link>https://dev.to/pbinder_2e65897d5/one-screenshot-is-sometimes-better-than-a-screen-recording-4d7h</link>
      <guid>https://dev.to/pbinder_2e65897d5/one-screenshot-is-sometimes-better-than-a-screen-recording-4d7h</guid>
      <description>&lt;p&gt;I kept running into the same small workflow problem.&lt;/p&gt;

&lt;p&gt;Whenever I needed to explain a browser process, report a UI bug, or document a quick internal step-by-step flow, the routine was usually the same: take a screenshot, open an image editor, draw arrows, add step numbers, export the image, and then send it.&lt;/p&gt;

&lt;p&gt;None of that is especially difficult, but it adds friction when the goal is just to explain something quickly.&lt;/p&gt;

&lt;p&gt;So I built a small Chrome extension called &lt;strong&gt;ClickTrek&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;ClickTrek records the clicks you make on the current page after starting it, then turns them into a single annotated PNG with numbered markers and arrows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9b4e89nw2ksawq9ex8u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl9b4e89nw2ksawq9ex8u.png" alt="Example ClickTrek output" width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem I Wanted to Solve&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are already many good tools for documentation, screenshots, and screen recording. Loom, Scribe, Tango, Snagit, CleanShot, and similar tools are useful for full walkthroughs, polished docs, or more detailed editing.&lt;/p&gt;

&lt;p&gt;But I wanted something narrower.&lt;/p&gt;

&lt;p&gt;Sometimes a video or hosted walkthrough is more than I need. I just want one image that clearly shows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click here.&lt;/li&gt;
&lt;li&gt;Then click here.&lt;/li&gt;
&lt;li&gt;Then click here.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That specific use case is what ClickTrek is focused on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How It Works&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ClickTrek is designed for quick browser workflow documentation.&lt;/p&gt;

&lt;p&gt;It currently handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;recording clicks on the current page&lt;/li&gt;
&lt;li&gt;adding numbered step markers&lt;/li&gt;
&lt;li&gt;drawing arrows between steps&lt;/li&gt;
&lt;li&gt;undoing accidental clicks&lt;/li&gt;
&lt;li&gt;showing a preview before export&lt;/li&gt;
&lt;li&gt;downloading the final result as a PNG&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The output is a single image you can drop into a bug report, GitHub issue, Slack message, internal wiki, tutorial, or handoff note.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why I Kept It Simple And Local&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first version is intentionally small. I wanted the flow to be easy to understand: open it, start recording, click through the workflow, preview, and export.&lt;/p&gt;

&lt;p&gt;There is no account setup, no cloud upload, and no hosted workspace.&lt;/p&gt;

&lt;p&gt;ClickTrek runs locally in the browser. It captures the visible page to generate the PNG, and the final export is saved through the browser download flow.&lt;/p&gt;

&lt;p&gt;One important note: anything visible on the page can appear in the exported image, so the preview step matters. You should review the image before sharing it.&lt;/p&gt;

&lt;p&gt;ClickTrek is not trying to replace full documentation platforms or screen recording tools. It is meant for the smaller moments where a quick annotated image is enough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current Limitations And What Might Come Next&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The main limitation right now is that ClickTrek only supports single-page workflows.&lt;/p&gt;

&lt;p&gt;If you navigate away to another page, the current capture ends. Since many real workflows span multiple pages, this is one of the biggest things I am thinking about for future versions.&lt;/p&gt;

&lt;p&gt;Other features I am considering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multi-page workflow capture&lt;/li&gt;
&lt;li&gt;blur or redaction tools for sensitive data&lt;/li&gt;
&lt;li&gt;PDF and Markdown export&lt;/li&gt;
&lt;li&gt;copy-to-clipboard export&lt;/li&gt;
&lt;li&gt;custom marker colors and styles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am still figuring out which of these would add the most value without making the tool feel heavy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try It&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ClickTrek is available on the Chrome Web Store:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chromewebstore.google.com/detail/clicktrek/iokpiefcbiiccjklbocmboepebifhpaj" rel="noopener noreferrer"&gt;Get ClickTrek on the Chrome Web Store&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I would be interested to hear how people currently document quick browser workflows for bug reports, tutorials, internal docs, or handoff notes.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>productivity</category>
      <category>chromeextension</category>
      <category>showdev</category>
    </item>
    <item>
      <title>JavaScript DOM</title>
      <dc:creator>Anees Abdul</dc:creator>
      <pubDate>Tue, 28 Apr 2026 14:31:59 +0000</pubDate>
      <link>https://dev.to/anees_abdul_ec1dda9c7697b/javascript-dom-194k</link>
      <guid>https://dev.to/anees_abdul_ec1dda9c7697b/javascript-dom-194k</guid>
      <description>&lt;ul&gt;
&lt;li&gt;DOM stands for Document Object Model.&lt;/li&gt;
&lt;li&gt;Document can be any file(HTML, XML), object can be Tags and Elements
(h1 and p) And the model is the layout of the structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz7wqrk0wvc2pynqz7m6s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz7wqrk0wvc2pynqz7m6s.png" alt=" " width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is HTML DOM:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The HTML DOM is a standard object model and programming interface for HTML&lt;/li&gt;
&lt;li&gt;It defines:

&lt;ul&gt;
&lt;li&gt;The HTML elements as objects and the properties of all HTML elements, and also the methods to access the elements.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;In simple words, it is a standard for how to get, change, add, or delete HTML elements&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why is DOM needed:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using this, we can change the HTML elements, attributes, and CSS styles in the page&lt;/li&gt;
&lt;li&gt;We can add/remove existing HTML elements and attributes&lt;/li&gt;
&lt;li&gt;React to events from HTML elements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How to select Elements:&lt;/strong&gt;&lt;br&gt;
-Selecting HTML elements using JavaScript so we can interact with them.&lt;/p&gt;

&lt;p&gt;There are several ways to find elements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Finding Elements by id&lt;/li&gt;
&lt;li&gt;Finding Elements by tag name&lt;/li&gt;
&lt;li&gt;Finding Elements by class name&lt;/li&gt;
&lt;li&gt;Finding Elements by css selectors&lt;/li&gt;
&lt;li&gt;Finding Elements by HTML object collections&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;1. Find Elements by id:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the element is found, the method will return the element as an object(in Element)&lt;/li&gt;
&lt;li&gt;If the element is not found then it will contain null
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;//Hello World&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;2. Find Elements by TagName:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;First&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Second&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eleByTag&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;getElementsByTagName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;p&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eleByTag&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;innerText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="sr"&gt;/Firs&lt;/span&gt;&lt;span class="err"&gt;t
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Find Elements by ClassName:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;First&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Second&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eleByTag&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;getElementsByClassName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eleByTag&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;innerText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;//Second&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Find Elements by CSS selectors:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSS selectors allow us to access DOM elements using querySelector and querySelectorAll by specifying id, class, tag, or more complex patterns.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is querySelector():&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It will return the first matching Element
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;p&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;World&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="sr"&gt;/ return only the first match and second is ignore&lt;/span&gt;&lt;span class="err"&gt;d
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If you want to select all matching elements then go for querySelectorAll()&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is querySelectorAll():&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It will return the all matching elements(Node List)&lt;/li&gt;
&lt;li&gt;If you want to access one element at a time then mention the index
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;First&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Second&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Third&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selector&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;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.two&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selector&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="nx"&gt;innerText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="sr"&gt;/Thir&lt;/span&gt;&lt;span class="err"&gt;d
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;You can also Loop through all when using querySelectorAll()
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;First&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Second&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Third&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selector&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;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.two&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;selector&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="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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;//Second,Third&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Find Elemnts using Collections(HTML collection/NodeList):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;-It will return multiple elements so use getElementsBy&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When multiple elements are returned, we must iterate through the collection using loops or forEach to access individual elements.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;one&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;First&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Second&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;   &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;two&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Third&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selector&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;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.two&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;selector&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="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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selector&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="nx"&gt;innerText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;//Third&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How to Change Elements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The HTML DOM allows JavaScript to change both the text and the content of HTML elements.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1. Change the content of an &lt;h1&gt;element:&lt;/h1&gt;&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Ele&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;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Changed Element&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Ele&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;//Changed Element&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Changing the attribute:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;img&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;old.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;img&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;img&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;new.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;//new.png&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Changing CSS style:&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Hello&lt;/span&gt; &lt;span class="nx"&gt;World&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Ele&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;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;Ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;Ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fontSize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;20px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;Ele&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Blue&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How to create elements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The createElement() method creates an element node.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Old&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// Create element:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;para&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;p&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;para&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;changed paragraph&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Append to body:&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&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;para&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="nx"&gt;O&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Testing&lt;/span&gt; &lt;span class="nx"&gt;Paragraph&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
     &lt;span class="nx"&gt;changed&lt;/span&gt; &lt;span class="nx"&gt;Paragraph&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How to remove Elements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The remove() method removes an element (or node) from the document.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;How to setAttribute():&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;-setAttribute() is used to add or update an HTML attribute of an element&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Click&lt;/span&gt; &lt;span class="nx"&gt;Me&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;btn&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;btn&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;submit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>beginners</category>
      <category>html</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>X Banned Me During My Product Hunt Launch. Then Medium Saved Me.</title>
      <dc:creator>Aritomo Fukuda</dc:creator>
      <pubDate>Tue, 28 Apr 2026 14:30:22 +0000</pubDate>
      <link>https://dev.to/aritomofukuda/x-banned-me-during-my-product-hunt-launch-then-medium-saved-me-498l</link>
      <guid>https://dev.to/aritomofukuda/x-banned-me-during-my-product-hunt-launch-then-medium-saved-me-498l</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjrwur82gkdj2t8bv3g4r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjrwur82gkdj2t8bv3g4r.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Twelve days ago, I launched OriginBrief on Product Hunt.&lt;/p&gt;

&lt;p&gt;The launch went live, the comments started rolling in, and I did what any indie founder would do — I replied. To every single one.&lt;/p&gt;

&lt;p&gt;Around 15 replies. Maybe 1–2 hours. Six of them included a link to my product.&lt;/p&gt;

&lt;p&gt;That was apparently a crime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Suspension&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The next morning, my &lt;a class="mentioned-user" href="https://dev.to/aritomofukuda"&gt;@aritomofukuda&lt;/a&gt; account was frozen. No warning. No explanation. Just gone.&lt;/p&gt;

&lt;p&gt;I filed an appeal. Crickets. I waited. Eleven days passed.&lt;/p&gt;

&lt;p&gt;Eleven days during the most critical post-launch window — when comments need replies, when potential users have questions, when the algorithm starts deciding if you matter.&lt;/p&gt;

&lt;p&gt;X’s spam detection had decided I was a bot. Because I replied to people too quickly. Because I shared my own product more than once. Because the engineers at X apparently can’t tell the difference between a startup founder and a spammer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Numbers Don’t Lie&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let me show you what I actually did:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total tweets that day: ~15&lt;/li&gt;
&lt;li&gt;Tweets containing a link: 6 (5 replies + 1 launch announcement)&lt;/li&gt;
&lt;li&gt;Pace: roughly one every 6–15 minutes&lt;/li&gt;
&lt;li&gt;Time window: 1–2 hours&lt;/li&gt;
&lt;li&gt;Links pointed to: my own product (not a phishing site, not a sketchy affiliate, not a competitor’s page)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m a human being. I had just shipped something. I was excited. I was reaching out to my community on a launch day.&lt;/p&gt;

&lt;p&gt;And X decided that was indistinguishable from spam.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I Lost&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For 11 days, I lost:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The ability to reply to my Product Hunt commenters&lt;/li&gt;
&lt;li&gt;Connection with the indie hackers community I’d been building relationships in&lt;/li&gt;
&lt;li&gt;Real-time growth signals that X provides during a launch&lt;/li&gt;
&lt;li&gt;A meaningful portion of my expected post-launch reach&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For an indie founder running on zero budget, that’s not a small loss. That’s the entire short-term growth lever, gone.&lt;/p&gt;

&lt;p&gt;Download the Medium App&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Plot Twist&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here’s where it gets interesting.&lt;/p&gt;

&lt;p&gt;Because X was dead, I had to do something I’d been avoiding: write longer-form content. So I started posting on Medium. Not every day, but consistently. Six articles in twelve days, mostly about the unglamorous reality of solo SaaS launches.&lt;/p&gt;

&lt;p&gt;This week, I got my first “Read” — meaning someone actually read one of my articles to the end, not just clicked.&lt;/p&gt;

&lt;p&gt;Today, the editorial team of Startup Stash sent me a private note. They have nearly 1,000 followers on Medium. They invited me to write for them.&lt;/p&gt;

&lt;p&gt;Twelve days ago, I depended on X.&lt;/p&gt;

&lt;p&gt;Today, I have a publication invitation and a relationship with editors who care about the work — not algorithms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Lesson&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It’s not that X is evil. It’s that X is &lt;strong&gt;a platform you don’t control.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Their spam detection is a black box. Their appeal system is a void. Their support, post-Musk, has effectively stopped existing for individual creators. You can spend years building a following, and one day, an algorithm flips a bit and you’re gone.&lt;/p&gt;

&lt;p&gt;The only sustainable channels for indie founders are the ones you own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your domain&lt;/li&gt;
&lt;li&gt;Your email list&lt;/li&gt;
&lt;li&gt;Your content on platforms that have functioning editorial relationships&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Medium isn’t perfect. But when an editor at Startup Stash decides your work fits their audience, that’s a relationship — not a coin flip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I’m Doing Now&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Still posting on Medium, now with publication amplification&lt;/li&gt;
&lt;li&gt;Running the SEO content engine on my SaaS that auto-generates weekly reports (the original reason I built OriginBrief)&lt;/li&gt;
&lt;li&gt;Leaving X to recover or not — at this point, it’s optional&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re building in public and X is your primary channel, please understand: you’re one false-positive away from losing it all. Build owned channels in parallel. Right now. Before you need them.&lt;/p&gt;

&lt;p&gt;I learned this the hard way over the last 11 days.&lt;/p&gt;

&lt;p&gt;Maybe this saves you from learning it the same way.&lt;/p&gt;

&lt;p&gt;— -&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I’m Aritomo, a 25-year engineer trying to figure out marketing as a solo founder. I’m building four SaaS products: StandupFlow, QuietLog, DocDecay, and OriginBrief. This is the kind of stuff I write about — usually with disclaimers about how little I know.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I might be reading too much into 11 days of bad luck. Maybe X will unfreeze me tomorrow. Maybe Startup Stash will publish my piece and 3 people will read it. The point isn’t that I’m now successful — it’s that I’m no longer dependent on a single platform. That alone is worth the 11 days.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>saas</category>
    </item>
  </channel>
</rss>
