<?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: Dulaj Thiwanka</title>
    <description>The latest articles on DEV Community by Dulaj Thiwanka (@dthiwanka).</description>
    <link>https://dev.to/dthiwanka</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2077437%2Fa3d1890d-6e6d-4ae7-98ca-51a2949ec3de.jpg</url>
      <title>DEV Community: Dulaj Thiwanka</title>
      <link>https://dev.to/dthiwanka</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dthiwanka"/>
    <language>en</language>
    <item>
      <title>Asterism: Turning Large Codebases into Interactive Visual Maps</title>
      <dc:creator>Dulaj Thiwanka</dc:creator>
      <pubDate>Fri, 11 Sep 2026 23:05:42 +0000</pubDate>
      <link>https://dev.to/dthiwanka/asterism-turning-large-codebases-into-interactive-visual-maps-2po3</link>
      <guid>https://dev.to/dthiwanka/asterism-turning-large-codebases-into-interactive-visual-maps-2po3</guid>
      <description>&lt;h2&gt;
  
  
  Asterism: Turning Large Codebases into Interactive Visual Maps
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl4hxpuq9isp09v6clg3m.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl4hxpuq9isp09v6clg3m.jpg" alt="Asterism" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Subtitle:&lt;/strong&gt; How I built a VS Code extension that uses language-server capabilities and interactive graphs to help developers understand how code is connected.&lt;/p&gt;




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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpyb8k3y2cto8ignkrnng.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpyb8k3y2cto8ignkrnng.jpg" alt="intro" width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;
Understanding a large codebase is one of the hardest parts of software development.&lt;/p&gt;

&lt;p&gt;When joining an unfamiliar project, developers often start by opening files and following imports, function calls, class definitions, and references manually. That works reasonably well for small projects, but becomes increasingly difficult as the codebase grows.&lt;/p&gt;

&lt;p&gt;A function may call another function several layers deep. A class may inherit from another class defined in a different folder. A variable may be used across multiple methods. A change to one symbol may affect code that is not immediately obvious from the file being edited.&lt;/p&gt;

&lt;p&gt;The problem isn't necessarily that the code is poorly written.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem is that the relationships inside the codebase are difficult to see.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That observation led to my idea for &lt;strong&gt;Asterism&lt;/strong&gt;, a VS Code extension designed to turn those relationships into an interactive visual map.&lt;/p&gt;

&lt;p&gt;Instead of only reading code line by line, developers can explore a graph of functions, methods, classes, interfaces, variables, files, and folders — and move between that visual representation and the actual source code.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Problem with Understanding Large Codebases
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa123mbkhnl1lheiducsu.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa123mbkhnl1lheiducsu.jpg" alt="problem" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Software is naturally represented as text.&lt;/p&gt;

&lt;p&gt;Developers write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function A() {
    B();
}

function B() {
    C();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A human can understand this small example immediately.&lt;/p&gt;

&lt;p&gt;But imagine the same relationship spread across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;500 files&lt;/li&gt;
&lt;li&gt;thousands of functions&lt;/li&gt;
&lt;li&gt;dozens of classes&lt;/li&gt;
&lt;li&gt;multiple inheritance relationships&lt;/li&gt;
&lt;li&gt;shared variables&lt;/li&gt;
&lt;li&gt;deeply nested folders&lt;/li&gt;
&lt;li&gt;several layers of abstraction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finding relationships manually becomes expensive.&lt;/p&gt;

&lt;p&gt;Consider a seemingly simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If I change this function, what other parts of the application might be affected?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You may need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find the function.&lt;/li&gt;
&lt;li&gt;Find its references.&lt;/li&gt;
&lt;li&gt;Identify callers.&lt;/li&gt;
&lt;li&gt;Inspect those callers.&lt;/li&gt;
&lt;li&gt;Follow additional calls.&lt;/li&gt;
&lt;li&gt;Check related classes.&lt;/li&gt;
&lt;li&gt;Check inherited implementations.&lt;/li&gt;
&lt;li&gt;Check variables or fields being used.&lt;/li&gt;
&lt;li&gt;Navigate between multiple files.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The information exists inside the codebase, but it is distributed across many source files and language constructs.&lt;/p&gt;

&lt;p&gt;Asterism approaches the problem from a different direction:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What if the relationships already understood by the development environment could be turned into an interactive graph?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What Is Asterism?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F71lcq0qeim6qiu8yt0yh.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F71lcq0qeim6qiu8yt0yh.jpg" alt="asterminwhat" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Asterism&lt;/strong&gt; is a Visual Studio Code extension for exploring the structure and relationships of a codebase through interactive graphs.&lt;/p&gt;

&lt;p&gt;The name comes from the astronomical concept of an &lt;strong&gt;asterism&lt;/strong&gt; — a recognizable pattern formed by stars.&lt;/p&gt;

&lt;p&gt;That idea maps nicely to software.&lt;/p&gt;

&lt;p&gt;A codebase contains many individual "points":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Functions&lt;/li&gt;
&lt;li&gt;Methods&lt;/li&gt;
&lt;li&gt;Classes&lt;/li&gt;
&lt;li&gt;Interfaces&lt;/li&gt;
&lt;li&gt;Variables&lt;/li&gt;
&lt;li&gt;Files&lt;/li&gt;
&lt;li&gt;Folders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And relationships connect those points.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             ┌─────────────┐
             │ Controller  │
             └──────┬──────┘
                    │ calls
                    ▼
             ┌─────────────┐
             │  Service    │
             └──────┬──────┘
                    │ calls
                    ▼
             ┌─────────────┐
             │ Repository  │
             └─────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Asterism turns relationships like these into an interactive graph that developers can explore.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Asterism Works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq6bb6d1l5x0g62icgosz.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq6bb6d1l5x0g62icgosz.jpg" alt="howworks" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At a high level, the process looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VS Code Workspace
       │
       ▼
Workspace Scanner
       │
       ▼
VS Code Language APIs
       │
       ├── Symbols
       ├── Calls
       ├── References
       ├── Definitions
       └── Type Relationships
       │
       ▼
Relationship Model
       │
       ▼
Graph Generation
       │
       ▼
Cytoscape.js
       │
       ▼
Interactive Webview
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important design decision here is that Asterism does &lt;strong&gt;not&lt;/strong&gt; try to build a custom parser for every programming language.&lt;/p&gt;

&lt;p&gt;Instead, it makes use of capabilities that VS Code and the installed language extensions already provide.&lt;/p&gt;

&lt;p&gt;That makes the architecture considerably more language-neutral.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Language-Server Advantage
&lt;/h2&gt;

&lt;p&gt;One of the most important technical decisions in Asterism is relying on &lt;strong&gt;VS Code's language-service and language-server ecosystem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Modern development environments already understand a lot about source code.&lt;/p&gt;

&lt;p&gt;Depending on the language and installed extension, VS Code can provide information about things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Symbols&lt;/li&gt;
&lt;li&gt;Definitions&lt;/li&gt;
&lt;li&gt;References&lt;/li&gt;
&lt;li&gt;Call hierarchies&lt;/li&gt;
&lt;li&gt;Incoming calls&lt;/li&gt;
&lt;li&gt;Outgoing calls&lt;/li&gt;
&lt;li&gt;Type hierarchies&lt;/li&gt;
&lt;li&gt;Implementations&lt;/li&gt;
&lt;li&gt;Symbol relationships&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rather than rebuilding all of that knowledge from scratch, Asterism asks VS Code's language infrastructure for the information it needs.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source Code
    │
    ▼
Language Extension
    │
    ▼
Language Server / Service
    │
    ▼
VS Code APIs
    │
    ▼
Asterism
    │
    ▼
Interactive Graph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is particularly useful because programming languages have very different syntax and semantics.&lt;/p&gt;

&lt;p&gt;A custom parser-based approach would require maintaining language-specific parsing and analysis logic.&lt;/p&gt;

&lt;p&gt;With Asterism's approach, much of that language-specific work remains within the existing VS Code ecosystem.&lt;/p&gt;

&lt;h3&gt;
  
  
  A practical consequence
&lt;/h3&gt;

&lt;p&gt;If VS Code has appropriate language support installed for a programming language, Asterism can potentially use the information exposed by that language support.&lt;/p&gt;

&lt;p&gt;The quality and completeness of the resulting graph therefore depend partly on what the language service provides.&lt;/p&gt;




&lt;h2&gt;
  
  
  Main Features
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu7oht11xssjt3qczo1ol.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu7oht11xssjt3qczo1ol.jpg" alt="mainfeatures" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Asterism is built around several kinds of code relationships.&lt;/p&gt;

&lt;h2&gt;
  
  
  Function and Method Calls
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp347vrde488m40gny6oj.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fp347vrde488m40gny6oj.jpg" alt="functionandmethod" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The graph can show relationships between functions and methods.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;authenticate()
      │
      ▼
validateUser()
      │
      ▼
findUser()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it possible to explore both directions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Outgoing calls:&lt;/strong&gt; What does this function call?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Incoming calls:&lt;/strong&gt; What calls this function?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is useful when investigating execution flow or estimating the potential impact of a change.&lt;/p&gt;




&lt;h2&gt;
  
  
  Class Inheritance
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fadedaothnkl1l9tx2zlb.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fadedaothnkl1l9tx2zlb.jpg" alt="classinheritance" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Object-oriented code often contains relationships that are difficult to understand when spread across multiple files.&lt;/p&gt;

&lt;p&gt;Asterism can visualize inheritance relationships:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BaseController
       ▲
       │ inherits
       │
UserController
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This provides another dimension of understanding beyond function calls.&lt;/p&gt;




&lt;h2&gt;
  
  
  Interface Implementations
&lt;/h2&gt;

&lt;p&gt;Interfaces can also form important architectural relationships.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PaymentProvider
       ▲
       │ implements
       │
StripePaymentProvider
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visualizing these relationships can make larger object-oriented systems easier to navigate.&lt;/p&gt;




&lt;h2&gt;
  
  
  Variable and Field References
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnpyeermmes8zv4csxwjk.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnpyeermmes8zv4csxwjk.jpg" alt="variableandfield" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not every important relationship is a function call.&lt;/p&gt;

&lt;p&gt;A function may depend heavily on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A global variable&lt;/li&gt;
&lt;li&gt;A class field&lt;/li&gt;
&lt;li&gt;A shared object&lt;/li&gt;
&lt;li&gt;A configuration value&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Asterism can represent relationships involving variables and class fields as well.&lt;/p&gt;

&lt;p&gt;This helps answer questions such as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which parts of the code use this value?"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  From Workspace to Graph
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fswf6gq87jbmxetkhheki.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fswf6gq87jbmxetkhheki.jpg" alt="graph" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The typical Asterism workflow is intentionally simple.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Open a project
&lt;/h3&gt;

&lt;p&gt;Open an existing project or workspace in VS Code.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Open Asterism
&lt;/h3&gt;

&lt;p&gt;Click the Asterism icon in the VS Code Activity Bar.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Workspace scanning
&lt;/h3&gt;

&lt;p&gt;Asterism scans the workspace and builds its available file representation.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Browse the project
&lt;/h3&gt;

&lt;p&gt;The Activity Bar sidebar provides a workspace-oriented view of folders and files.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Search
&lt;/h3&gt;

&lt;p&gt;If the project is large, developers can search for a file rather than manually navigating through folders.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Generate a graph
&lt;/h3&gt;

&lt;p&gt;Click a file to generate a graph related to that source.&lt;/p&gt;

&lt;p&gt;You can also generate a graph representing the workspace.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Explore
&lt;/h3&gt;

&lt;p&gt;Once the graph appears, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click nodes&lt;/li&gt;
&lt;li&gt;Search symbols&lt;/li&gt;
&lt;li&gt;Filter relationships&lt;/li&gt;
&lt;li&gt;Trace connected nodes&lt;/li&gt;
&lt;li&gt;Collapse structures&lt;/li&gt;
&lt;li&gt;Double-click symbols&lt;/li&gt;
&lt;li&gt;Follow symbols under the cursor&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8. Return to source code
&lt;/h3&gt;

&lt;p&gt;Double-clicking a symbol allows you to jump back to its source code.&lt;/p&gt;

&lt;p&gt;The goal is to make visual exploration and traditional code navigation work together rather than treating them as separate workflows.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Activity Bar Workflow
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhmdn6rze35n869fyvz93.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhmdn6rze35n869fyvz93.jpg" alt="activitybar" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the usability decisions behind Asterism was to make the extension feel like a natural part of VS Code.&lt;/p&gt;

&lt;p&gt;Instead of requiring developers to remember commands or navigate complicated menus, Asterism has a dedicated entry point in the &lt;strong&gt;Activity Bar&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The workflow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Activity Bar
     │
     ▼
Asterism Sidebar
     │
     ├── Browse folders
     ├── Browse files
     ├── Search
     └── Workspace graph
              │
              ▼
        Interactive graph
              │
              ▼
         Source code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This reduces the number of steps required to move from:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"I want to understand this part of the project"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Show me how this code is connected."&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Keeping Large Graphs Understandable
&lt;/h2&gt;

&lt;p&gt;A graph can become difficult to use if everything is displayed at once.&lt;/p&gt;

&lt;p&gt;Imagine a graph containing hundreds or thousands of nodes.&lt;/p&gt;

&lt;p&gt;Even if the underlying data is correct, displaying everything simultaneously can produce something visually overwhelming.&lt;/p&gt;

&lt;p&gt;Asterism therefore provides several mechanisms for controlling graph complexity.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqwg6pedgoqatktyitaby.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqwg6pedgoqatktyitaby.jpg" alt="grouping" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Grouping
&lt;/h2&gt;

&lt;p&gt;Nodes can be grouped by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Folder&lt;/li&gt;
&lt;li&gt;File&lt;/li&gt;
&lt;li&gt;No group&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
 ├── controllers/
 │     ├── UserController
 │     └── AuthController
 │
 ├── services/
 │     ├── UserService
 │     └── AuthService
 │
 └── repositories/
       └── UserRepository
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Grouping provides a higher-level structure around the graph.&lt;/p&gt;




&lt;h2&gt;
  
  
  Collapsing
&lt;/h2&gt;

&lt;p&gt;Folders, files, and classes can be collapsed.&lt;/p&gt;

&lt;p&gt;Instead of showing every individual node:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UserService
 ├── createUser()
 ├── updateUser()
 ├── deleteUser()
 ├── validateUser()
 └── notifyUser()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the graph can represent the larger structure more compactly.&lt;/p&gt;

&lt;p&gt;This is important because visualization is not simply about displaying more information.&lt;/p&gt;

&lt;p&gt;It is about displaying &lt;strong&gt;the right amount of information at the right time&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Filtering Relationships
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa0wvzbfrcfsstw6jtlkg.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa0wvzbfrcfsstw6jtlkg.jpg" alt="filtering" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not every relationship is useful for every investigation.&lt;/p&gt;

&lt;p&gt;Sometimes you only care about function calls.&lt;/p&gt;

&lt;p&gt;At another point, you may want to understand inheritance.&lt;/p&gt;

&lt;p&gt;Asterism provides filtering for relationship categories including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calls&lt;/li&gt;
&lt;li&gt;Inheritance&lt;/li&gt;
&lt;li&gt;Variable references&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows developers to reduce visual noise while investigating a particular question.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Show me only the call flow."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;rather than:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Show me every relationship the system knows about."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Searching Inside the Graph
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpd25hcn3jcjs69g7v2n1.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpd25hcn3jcjs69g7v2n1.jpg" alt="searching" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Large graphs introduce another navigation problem.&lt;/p&gt;

&lt;p&gt;Even after generating a graph, finding one particular symbol can be difficult.&lt;/p&gt;

&lt;p&gt;Asterism therefore supports symbol search inside the graph.&lt;/p&gt;

&lt;p&gt;This allows a developer to move from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I know the symbol I need."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Show me where that symbol sits in the architecture."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That combination of search + visualization is particularly useful for large projects.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tracing Connections
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnfdc3eunh1kboqrrgomi.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnfdc3eunh1kboqrrgomi.jpg" alt="tracing" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Asterism also allows developers to select a node and trace its relationships.&lt;/p&gt;

&lt;p&gt;The idea is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              A
              │
              ▼
        ┌─────B─────┐
        │            │
        ▼            ▼
        C            D
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Selecting &lt;code&gt;B&lt;/code&gt; can make its surrounding relationships easier to identify.&lt;/p&gt;

&lt;p&gt;This helps developers focus on a specific part of a larger graph without losing the broader context.&lt;/p&gt;




&lt;h2&gt;
  
  
  Following the Symbol Under the Cursor
&lt;/h2&gt;

&lt;p&gt;Another useful workflow is following the symbol currently under the cursor.&lt;/p&gt;

&lt;p&gt;Instead of manually generating a new graph every time you move to another symbol, Asterism can use the active symbol to update the graph.&lt;/p&gt;

&lt;p&gt;This creates a more continuous workflow between code editing and visual exploration.&lt;/p&gt;




&lt;h2&gt;
  
  
  Jumping Between Graph and Source Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5zn2qr2cqb62gyoo0sbl.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5zn2qr2cqb62gyoo0sbl.jpg" alt="jumping" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Visualization is useful, but developers ultimately work with source code.&lt;/p&gt;

&lt;p&gt;Asterism therefore treats the graph as a navigation layer rather than a replacement for the editor.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F198d0xlga56vcj0ul7d4.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F198d0xlga56vcj0ul7d4.jpg" alt="description" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Double-clicking a symbol can take the developer back to its source.&lt;/p&gt;

&lt;p&gt;The workflow becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source
  ↓
Graph
  ↓
Explore relationship
  ↓
Select symbol
  ↓
Open source
  ↓
Continue investigation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a feedback loop between visual understanding and actual implementation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Visual Code Maps Are Useful
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3fy3p3rv60bj9po11f6x.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3fy3p3rv60bj9po11f6x.jpg" alt="visual" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The usefulness of a graph depends on the question being asked.&lt;/p&gt;

&lt;p&gt;There are several situations where visual relationships can be particularly helpful.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Learning an unfamiliar project
&lt;/h2&gt;

&lt;p&gt;When joining a new project, developers need to build a mental model.&lt;/p&gt;

&lt;p&gt;A visual map can help answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where are the important components?&lt;/li&gt;
&lt;li&gt;Which functions connect?&lt;/li&gt;
&lt;li&gt;Which classes depend on others?&lt;/li&gt;
&lt;li&gt;Where does execution flow?&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqn3igndxml1d6cjnw0zc.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqn3igndxml1d6cjnw0zc.jpg" alt="description" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Planning refactoring
&lt;/h2&gt;

&lt;p&gt;Before changing a function or class, it is useful to understand its relationships.&lt;/p&gt;

&lt;p&gt;A graph can provide another perspective on potential dependencies.&lt;/p&gt;

&lt;p&gt;Instead of immediately modifying code, developers can first investigate how the symbol connects to the surrounding system.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4r6zxmsy3f3mdkmchvhh.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4r6zxmsy3f3mdkmchvhh.jpg" alt="description" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Understanding legacy systems
&lt;/h2&gt;

&lt;p&gt;Legacy applications often contain years of accumulated behavior.&lt;/p&gt;

&lt;p&gt;Documentation may be incomplete or outdated.&lt;/p&gt;

&lt;p&gt;The code itself becomes the most reliable source of information.&lt;/p&gt;

&lt;p&gt;A visual representation can help developers gradually reconstruct the system's structure.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Finding highly connected functions
&lt;/h2&gt;

&lt;p&gt;Some functions become central points in an application.&lt;/p&gt;

&lt;p&gt;They may have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many callers&lt;/li&gt;
&lt;li&gt;Many outgoing calls&lt;/li&gt;
&lt;li&gt;Numerous references&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These highly connected areas can be useful places to investigate when trying to understand architecture or potential change impact.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Reviewing dependencies
&lt;/h2&gt;

&lt;p&gt;A graph can provide a visual representation of relationships that are otherwise spread across files.&lt;/p&gt;

&lt;p&gt;This can make dependency investigation more approachable.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Investigating bugs
&lt;/h2&gt;

&lt;p&gt;When debugging, developers frequently ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How did execution get here?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Following incoming and outgoing relationships can help reconstruct the path surrounding a problematic symbol.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Developer onboarding
&lt;/h2&gt;

&lt;p&gt;New developers often need to understand a system before they can contribute effectively.&lt;/p&gt;

&lt;p&gt;A visual exploration tool can complement:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documentation&lt;/li&gt;
&lt;li&gt;Code reviews&lt;/li&gt;
&lt;li&gt;Architecture diagrams&lt;/li&gt;
&lt;li&gt;Existing development guides&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  8. Understanding inheritance
&lt;/h2&gt;

&lt;p&gt;Inheritance structures can become particularly difficult when classes are distributed across packages and directories.&lt;/p&gt;

&lt;p&gt;A graph makes those relationships easier to inspect.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Estimating change impact
&lt;/h2&gt;

&lt;p&gt;Before modifying an important symbol, developers can inspect its connections and identify areas that may deserve additional attention.&lt;/p&gt;

&lt;p&gt;It isn't a replacement for careful testing, but it can provide useful context before making a change.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technical Architecture
&lt;/h2&gt;

&lt;p&gt;Asterism is built around several core technologies.&lt;/p&gt;

&lt;h2&gt;
  
  
  TypeScript
&lt;/h2&gt;

&lt;p&gt;The extension is implemented using &lt;strong&gt;TypeScript&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;TypeScript provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static typing&lt;/li&gt;
&lt;li&gt;Better tooling&lt;/li&gt;
&lt;li&gt;Improved maintainability&lt;/li&gt;
&lt;li&gt;Strong integration with the VS Code extension ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For an extension that coordinates workspace scanning, language-service requests, graph generation, and UI communication, maintaining clear contracts between components is particularly useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  VS Code Extension API
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;VS Code Extension API&lt;/strong&gt; provides the foundation for Asterism.&lt;/p&gt;

&lt;p&gt;It gives the extension access to the development environment it is running inside.&lt;/p&gt;

&lt;p&gt;Asterism uses VS Code capabilities for things such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Workspace interaction&lt;/li&gt;
&lt;li&gt;File-system events&lt;/li&gt;
&lt;li&gt;Commands&lt;/li&gt;
&lt;li&gt;Activity Bar integration&lt;/li&gt;
&lt;li&gt;Sidebar views&lt;/li&gt;
&lt;li&gt;Language-service/provider functionality&lt;/li&gt;
&lt;li&gt;Editor interaction&lt;/li&gt;
&lt;li&gt;Theme information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This lets Asterism behave as part of VS Code rather than as an entirely separate application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Language-Service Provider Commands
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqv4qwlbpecyu3lbfcsda.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqv4qwlbpecyu3lbfcsda.jpg" alt="description" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The language layer is one of the most important parts of the architecture.&lt;/p&gt;

&lt;p&gt;Rather than parsing every language independently, Asterism uses VS Code's available language-service capabilities to discover relationships.&lt;/p&gt;

&lt;p&gt;Conceptually, the extension asks questions such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What symbol is this?
       ↓
Where is it defined?
       ↓
What references it?
       ↓
What does it call?
       ↓
What calls it?
       ↓
What types are related to it?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact information available can vary depending on the language extension and language server.&lt;/p&gt;

&lt;p&gt;That variability is an important part of the architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cytoscape.js
&lt;/h2&gt;

&lt;p&gt;Once relationships have been discovered, Asterism needs a way to render them.&lt;/p&gt;

&lt;p&gt;For this, it uses &lt;strong&gt;Cytoscape.js&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Cytoscape.js is designed for interactive graph and network visualization.&lt;/p&gt;

&lt;p&gt;Asterism represents code relationships using graph concepts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node  = code entity
Edge  = relationship
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;UserController ──calls──&amp;gt; UserService
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AdminController ──inherits──&amp;gt; BaseController
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a natural mapping between software architecture and graph structures.&lt;/p&gt;




&lt;h2&gt;
  
  
  fCoSE Layout
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3bc93a4a3k91sfe1e2mz.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3bc93a4a3k91sfe1e2mz.jpg" alt="fcose" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They also need to be positioned in a way that makes relationships understandable.&lt;/p&gt;

&lt;p&gt;Asterism uses the &lt;strong&gt;fCoSE graph layout&lt;/strong&gt; to organize graph structures.&lt;/p&gt;

&lt;p&gt;The purpose of the layout is to produce a more readable arrangement of interconnected nodes, particularly when grouping structures are involved.&lt;/p&gt;

&lt;p&gt;This matters because graph visualization is partly a data problem and partly a spatial problem.&lt;/p&gt;

&lt;p&gt;The same relationships can be much easier or harder to understand depending on how they are arranged visually.&lt;/p&gt;




&lt;h2&gt;
  
  
  Webviews
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9751rvp4d77ddqltj6yb.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9751rvp4d77ddqltj6yb.jpg" alt="webviews" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Asterism's interactive graph interface runs through a VS Code &lt;strong&gt;Webview&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This provides a bridge between the VS Code extension environment and web-based UI technologies.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VS Code Extension
       │
       │ messages / data
       ▼
     Webview
       │
       ▼
Cytoscape.js Graph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows the graph interface to provide interactive behaviors such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selecting nodes&lt;/li&gt;
&lt;li&gt;Searching&lt;/li&gt;
&lt;li&gt;Filtering&lt;/li&gt;
&lt;li&gt;Collapsing&lt;/li&gt;
&lt;li&gt;Tracing&lt;/li&gt;
&lt;li&gt;Navigating&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;while remaining inside VS Code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Activity Bar and Sidebar
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4i3ngyzar7yxcthe9xvr.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4i3ngyzar7yxcthe9xvr.jpg" alt="description" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Activity Bar provides the primary entry point for the extension.&lt;/p&gt;

&lt;p&gt;The sidebar handles workspace exploration and file selection.&lt;/p&gt;

&lt;p&gt;This separation is useful because it keeps two different concerns distinct:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sidebar&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What part of the project do I want to investigate?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Graph&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How is that part of the project connected?"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  VSIX Packaging
&lt;/h2&gt;

&lt;p&gt;Asterism is packaged as a &lt;strong&gt;VSIX&lt;/strong&gt;, the standard packaging format for VS Code extensions.&lt;/p&gt;

&lt;p&gt;This allows users to install the extension directly into VS Code.&lt;/p&gt;

&lt;p&gt;The same packaging approach also makes it possible to distribute the extension through the VS Code ecosystem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Language Support Through VS Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3bhua19q2y7eot8981ar.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3bhua19q2y7eot8981ar.jpg" alt="language" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Asterism's language strategy is worth emphasizing.&lt;/p&gt;

&lt;p&gt;It isn't designed around the assumption that one parser can understand every programming language.&lt;/p&gt;

&lt;p&gt;Instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Asterism
   │
   ▼
VS Code Language APIs
   │
   ▼
Installed Language Extension
   │
   ▼
Language Server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This provides an abstraction layer.&lt;/p&gt;

&lt;p&gt;For example, Asterism doesn't necessarily need to know every syntactic rule of a language in order to ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What calls this function?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The language service may already know that.&lt;/p&gt;

&lt;p&gt;Asterism's responsibility becomes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Request relationship information.&lt;/li&gt;
&lt;li&gt;Interpret the returned information.&lt;/li&gt;
&lt;li&gt;Convert it into a common internal graph representation.&lt;/li&gt;
&lt;li&gt;Render that representation.&lt;/li&gt;
&lt;li&gt;Let the developer interact with it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is one of the architectural choices that makes the project interesting to me.&lt;/p&gt;




&lt;h2&gt;
  
  
  Design and Usability Decisions
&lt;/h2&gt;

&lt;p&gt;Technical functionality is only part of building a developer tool.&lt;/p&gt;

&lt;p&gt;The other challenge is making the functionality easy to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simple Entry Point
&lt;/h2&gt;

&lt;p&gt;The Activity Bar provides an obvious place to start.&lt;/p&gt;

&lt;p&gt;Developers don't need to learn a complicated command sequence before seeing the extension.&lt;/p&gt;




&lt;h2&gt;
  
  
  Automatic Workspace Scanning
&lt;/h2&gt;

&lt;p&gt;Workspace scanning happens automatically.&lt;/p&gt;

&lt;p&gt;This removes an additional setup step and allows the sidebar to immediately represent the project.&lt;/p&gt;




&lt;h2&gt;
  
  
  Fast Path from File to Graph
&lt;/h2&gt;

&lt;p&gt;The sidebar is designed around a simple interaction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Find file → Click file → Explore graph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That keeps graph generation close to the user's existing project navigation workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  Grouping and Collapsing
&lt;/h2&gt;

&lt;p&gt;Large graphs can quickly become unreadable.&lt;/p&gt;

&lt;p&gt;Grouping and collapsing allow developers to move between different levels of abstraction.&lt;/p&gt;

&lt;p&gt;You can think of this as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Workspace
   ↓
Folder
   ↓
File
   ↓
Class
   ↓
Method
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user can decide how much detail is appropriate for the current investigation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Theme Integration
&lt;/h2&gt;

&lt;p&gt;A developer tool should feel native to its host environment.&lt;/p&gt;

&lt;p&gt;Asterism supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Light themes&lt;/li&gt;
&lt;li&gt;Dark themes&lt;/li&gt;
&lt;li&gt;High-contrast VS Code themes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows the graph interface to adapt to the developer's VS Code environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  Workspace File Updates
&lt;/h2&gt;

&lt;p&gt;Projects change constantly.&lt;/p&gt;

&lt;p&gt;Files can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created&lt;/li&gt;
&lt;li&gt;Edited&lt;/li&gt;
&lt;li&gt;Renamed&lt;/li&gt;
&lt;li&gt;Deleted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Asterism responds to these workspace changes and refreshes the file representation accordingly.&lt;/p&gt;

&lt;p&gt;This avoids treating the workspace as a static snapshot.&lt;/p&gt;




&lt;h2&gt;
  
  
  Performance Considerations
&lt;/h2&gt;

&lt;p&gt;Visualizing code relationships introduces practical limitations.&lt;/p&gt;

&lt;p&gt;Theoretically, a graph can contain a huge number of nodes and edges.&lt;/p&gt;

&lt;p&gt;Practically, that doesn't mean displaying everything at once is a good user experience.&lt;/p&gt;

&lt;p&gt;Asterism therefore applies limits intended to keep the interface usable.&lt;/p&gt;

&lt;p&gt;For example, it can limit the number of files and graph nodes involved in analysis.&lt;/p&gt;

&lt;p&gt;It also skips common generated or dependency-heavy directories such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node_modules/
dist/
build/
.venv/
venv/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These directories can contain large amounts of code that generally isn't useful when initially exploring the application's own source.&lt;/p&gt;




&lt;h2&gt;
  
  
  Language Server Startup
&lt;/h2&gt;

&lt;p&gt;Another practical consideration is that language servers may need time to initialize.&lt;/p&gt;

&lt;p&gt;If a language service is still loading or hasn't finished analyzing a workspace, the information returned to an extension may be incomplete.&lt;/p&gt;

&lt;p&gt;Therefore, the graph should not always be interpreted as an absolute representation of every relationship in the workspace at every instant.&lt;/p&gt;

&lt;p&gt;The quality of the results depends on the language support available in VS Code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Large Workspaces
&lt;/h2&gt;

&lt;p&gt;Very large workspaces may require adjusting configuration such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maximum files&lt;/li&gt;
&lt;li&gt;Call depth&lt;/li&gt;
&lt;li&gt;Graph limits&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The objective isn't to claim that every codebase can be visualized without constraints.&lt;/p&gt;

&lt;p&gt;The objective is to provide useful exploration while recognizing that code analysis and graph rendering both have practical boundaries.&lt;/p&gt;




&lt;h2&gt;
  
  
  Development Process and AI-Assisted Coding
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwf4il8zldpisz9f22p03.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwf4il8zldpisz9f22p03.jpg" alt="development" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Asterism began from my original idea and core concept.&lt;/p&gt;

&lt;p&gt;I defined the overall direction of the project, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The product concept&lt;/li&gt;
&lt;li&gt;Technical direction&lt;/li&gt;
&lt;li&gt;Feature requirements&lt;/li&gt;
&lt;li&gt;Architecture decisions&lt;/li&gt;
&lt;li&gt;User experience decisions&lt;/li&gt;
&lt;li&gt;Testing decisions&lt;/li&gt;
&lt;li&gt;Branding&lt;/li&gt;
&lt;li&gt;Integration requirements&lt;/li&gt;
&lt;li&gt;Packaging and release preparation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During implementation, I used &lt;strong&gt;GPT-5.6 LUNA Agentic Coding&lt;/strong&gt; as a development assistant.&lt;/p&gt;

&lt;p&gt;The AI-assisted workflow helped with areas such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exploring implementation approaches&lt;/li&gt;
&lt;li&gt;Generating and refining code&lt;/li&gt;
&lt;li&gt;Debugging&lt;/li&gt;
&lt;li&gt;Iterating on features&lt;/li&gt;
&lt;li&gt;Reasoning through technical problems&lt;/li&gt;
&lt;li&gt;Improving implementation details&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, this was an &lt;strong&gt;AI-assisted development process&lt;/strong&gt;, not an AI-owned project.&lt;/p&gt;

&lt;p&gt;The project direction, decisions, evaluation, testing, integration, and final development responsibility remained under my direction.&lt;/p&gt;

&lt;p&gt;I think this distinction is important.&lt;/p&gt;

&lt;p&gt;AI coding assistants can significantly change how software is developed, but using an AI tool doesn't mean the tool independently owns the product or replaces the developer's responsibility for architectural and engineering decisions.&lt;/p&gt;

&lt;p&gt;For Asterism, I treated AI as a development partner and coding assistant while remaining responsible for the project itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz3hxymnymila7u6lu7kd.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fz3hxymnymila7u6lu7kd.jpg" alt="lesson" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Building Asterism highlighted several lessons that extend beyond this particular project.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Use Existing Language Infrastructure
&lt;/h2&gt;

&lt;p&gt;One of the strongest lessons was the value of building on top of capabilities that already exist.&lt;/p&gt;

&lt;p&gt;Creating a parser and semantic analyzer for every supported language would dramatically increase the complexity of the project.&lt;/p&gt;

&lt;p&gt;Using VS Code's language ecosystem allows Asterism to focus more heavily on visualization and developer experience.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Language-Neutral Architecture Matters
&lt;/h2&gt;

&lt;p&gt;Different languages have different concepts and semantics.&lt;/p&gt;

&lt;p&gt;A language-neutral graph model provides an abstraction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Language-specific information
           ↓
     Common model
           ↓
      Graph nodes
           +
      Graph edges
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That separation makes it easier to think about relationships independently of syntax.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Mapping Language Results to Graph Nodes Is Difficult
&lt;/h2&gt;

&lt;p&gt;Getting information from a language service is only half the problem.&lt;/p&gt;

&lt;p&gt;That information needs to become stable graph entities.&lt;/p&gt;

&lt;p&gt;For example, the system needs to reason about:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Symbol
   ↓
Definition
   ↓
File
   ↓
Position
   ↓
Graph Node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Different language servers can return information with different levels of completeness.&lt;/p&gt;

&lt;p&gt;Connecting these results reliably is an important engineering challenge.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Incomplete Results Are Normal
&lt;/h2&gt;

&lt;p&gt;Language services aren't guaranteed to return perfect information at every moment.&lt;/p&gt;

&lt;p&gt;Workspaces may still be loading.&lt;/p&gt;

&lt;p&gt;Some symbols may not resolve.&lt;/p&gt;

&lt;p&gt;Some relationships may not be available.&lt;/p&gt;

&lt;p&gt;A robust visualization system needs to handle these cases gracefully rather than assuming that every query returns a complete dataset.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Large Graphs Need Constraints
&lt;/h2&gt;

&lt;p&gt;More data doesn't automatically mean more useful information.&lt;/p&gt;

&lt;p&gt;A graph with thousands of nodes might contain valuable information but still be practically impossible to understand.&lt;/p&gt;

&lt;p&gt;Grouping, filtering, collapsing, and sensible limits are therefore essential features rather than optional UI improvements.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. A Simple Sidebar Workflow Matters
&lt;/h2&gt;

&lt;p&gt;Developer tools compete with an existing workflow.&lt;/p&gt;

&lt;p&gt;If a developer needs to execute several commands just to inspect one file, the tool becomes harder to adopt.&lt;/p&gt;

&lt;p&gt;The Activity Bar → Sidebar → File → Graph workflow keeps the interaction simple.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Powerful Analysis vs. Readable Interface
&lt;/h2&gt;

&lt;p&gt;There is always a balance.&lt;/p&gt;

&lt;p&gt;More relationships can produce a more complete analysis.&lt;/p&gt;

&lt;p&gt;But displaying more relationships can also produce more visual noise.&lt;/p&gt;

&lt;p&gt;Asterism's development reinforced an important principle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A useful developer tool isn't necessarily the one that displays the most information. It's the one that makes the important information easier to understand.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F61lb3m1nwxjvwuzegm25.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F61lb3m1nwxjvwuzegm25.jpg" alt="future" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Asterism's current architecture leaves room for several future improvements.&lt;/p&gt;

&lt;p&gt;Some possibilities include:&lt;/p&gt;

&lt;h3&gt;
  
  
  Graph Export
&lt;/h3&gt;

&lt;p&gt;Export graph views as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PNG&lt;/li&gt;
&lt;li&gt;SVG&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This would make it easier to include visual architecture diagrams in documentation or technical discussions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Saved Graph Views
&lt;/h3&gt;

&lt;p&gt;Allow developers to save graph configurations for a workspace and return to them later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Analysis Caching
&lt;/h3&gt;

&lt;p&gt;Caching previously discovered relationships could reduce repeated analysis work in suitable situations.&lt;/p&gt;

&lt;h3&gt;
  
  
  External Library Visualization
&lt;/h3&gt;

&lt;p&gt;External library calls could potentially appear as visually differentiated or faded nodes, helping distinguish application code from dependencies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advanced Dependency Analysis
&lt;/h3&gt;

&lt;p&gt;Future versions could provide richer dependency relationships beyond the current graph categories.&lt;/p&gt;

&lt;h3&gt;
  
  
  Graph History
&lt;/h3&gt;

&lt;p&gt;A history mechanism could allow developers to move backward and forward between explored graph states.&lt;/p&gt;

&lt;h3&gt;
  
  
  Refactoring Impact Analysis
&lt;/h3&gt;

&lt;p&gt;A future impact-analysis feature could help developers investigate potential affected areas before modifying a symbol.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project-Level Summaries
&lt;/h3&gt;

&lt;p&gt;Higher-level summaries could provide a more architectural view of the project before diving into individual symbols.&lt;/p&gt;

&lt;h3&gt;
  
  
  More Language-Service Features
&lt;/h3&gt;

&lt;p&gt;As VS Code's language capabilities evolve, Asterism can potentially make use of additional language-service functionality.&lt;/p&gt;

&lt;h3&gt;
  
  
  More Language Edge Cases
&lt;/h3&gt;

&lt;p&gt;Automated testing around language-specific and language-server edge cases would help improve reliability across different projects and language environments.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installation and First Use
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgdp7ip2fvsdqhp7mojr5.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgdp7ip2fvsdqhp7mojr5.jpg" alt="install" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Asterism can be installed using the VSIX package or, when available, through the VS Code Marketplace.&lt;/p&gt;

&lt;p&gt;The general workflow is:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Install Asterism
&lt;/h2&gt;

&lt;p&gt;Install the VSIX through VS Code, or install Asterism from the Marketplace when it is available there.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Open a Workspace
&lt;/h3&gt;

&lt;p&gt;Open the project you want to investigate in VS Code.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Open Asterism
&lt;/h3&gt;

&lt;p&gt;Click the &lt;strong&gt;Asterism icon&lt;/strong&gt; in the Activity Bar.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Let the Workspace Scan
&lt;/h3&gt;

&lt;p&gt;Asterism scans the workspace and builds the file representation.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Choose What to Explore
&lt;/h3&gt;

&lt;p&gt;Select an individual file or generate a graph for the workspace.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Explore
&lt;/h3&gt;

&lt;p&gt;Use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search&lt;/li&gt;
&lt;li&gt;Filtering&lt;/li&gt;
&lt;li&gt;Node selection&lt;/li&gt;
&lt;li&gt;Tracing&lt;/li&gt;
&lt;li&gt;Grouping&lt;/li&gt;
&lt;li&gt;Collapsing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;to investigate the relationships.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Return to Code
&lt;/h3&gt;

&lt;p&gt;Double-click a symbol to jump back to its source code.&lt;/p&gt;

&lt;p&gt;The basic loop is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open project
    ↓
Open Asterism
    ↓
Scan workspace
    ↓
Select file / workspace
    ↓
Generate graph
    ↓
Explore relationships
    ↓
Jump back to source
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvvbw68pb5b7xwmo1azs5.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvvbw68pb5b7xwmo1azs5.jpg" alt="conclu" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Large codebases aren't difficult only because they contain a lot of code.&lt;/p&gt;

&lt;p&gt;They're difficult because the relationships between that code are distributed across thousands of individual elements.&lt;/p&gt;

&lt;p&gt;A developer might understand every function in isolation and still struggle to understand how the entire system fits together.&lt;/p&gt;

&lt;p&gt;That's the problem Asterism is trying to address.&lt;/p&gt;

&lt;p&gt;By combining &lt;strong&gt;VS Code's language-service capabilities&lt;/strong&gt;, &lt;strong&gt;TypeScript&lt;/strong&gt;, &lt;strong&gt;Cytoscape.js&lt;/strong&gt;, &lt;strong&gt;fCoSE&lt;/strong&gt;, &lt;strong&gt;Webviews&lt;/strong&gt;, and the &lt;strong&gt;VS Code Extension API&lt;/strong&gt;, Asterism turns code relationships into an interactive visual environment.&lt;/p&gt;

&lt;p&gt;The key idea isn't to replace source code with diagrams.&lt;/p&gt;

&lt;p&gt;It's to provide another way of looking at the same system.&lt;/p&gt;

&lt;p&gt;Instead of only asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What does this file contain?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;developers can also ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What is this connected to?"&lt;/p&gt;

&lt;p&gt;"What calls this?"&lt;/p&gt;

&lt;p&gt;"What does this call?"&lt;/p&gt;

&lt;p&gt;"Which classes are related?"&lt;/p&gt;

&lt;p&gt;"Where is this symbol used?"&lt;/p&gt;

&lt;p&gt;"What does the surrounding architecture look like?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That shift — from reading code exclusively as text to also exploring it as a network of relationships is the core idea behind Asterism.&lt;/p&gt;

&lt;p&gt;And as codebases continue to grow, I think tools that help developers &lt;strong&gt;see software structure rather than only read it&lt;/strong&gt; will become increasingly valuable.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd4vwwm95ci5xc46xi9dj.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fd4vwwm95ci5xc46xi9dj.jpg" alt="finalarchitecture" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Argon2 vs bcrypt vs PBKDF2 in Node.js: Which Password Hashing Algorithm Should You Use in 2026?</title>
      <dc:creator>Dulaj Thiwanka</dc:creator>
      <pubDate>Fri, 31 Jul 2026 06:25:32 +0000</pubDate>
      <link>https://dev.to/dthiwanka/argon2-vs-bcrypt-vs-pbkdf2-in-nodejs-which-password-hashing-algorithm-should-you-use-in-2026-eng</link>
      <guid>https://dev.to/dthiwanka/argon2-vs-bcrypt-vs-pbkdf2-in-nodejs-which-password-hashing-algorithm-should-you-use-in-2026-eng</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Password storage is one of the most important security decisions when building a backend application.&lt;/p&gt;

&lt;p&gt;A common mistake developers make is storing passwords using fast hashing algorithms like:&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="nc"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nc"&gt;MD5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These algorithms are designed to be fast, which makes them perfect for data integrity checks but terrible for password storage.&lt;/p&gt;

&lt;p&gt;If your database is leaked, attackers can use GPUs and password-cracking tools to test billions of passwords.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa2fz5zkigj9etcyl01jl.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa2fz5zkigj9etcyl01jl.png" alt="attackflow" width="799" height="436"&gt;&lt;/a&gt;&lt;br&gt;
Modern password hashing algorithms solve this problem by intentionally making password cracking expensive.&lt;/p&gt;

&lt;p&gt;The three most common choices in Node.js applications are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Argon2id&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;bcrypt&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PBKDF2&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article explains how each works and how to implement them correctly in Node.js applications.&lt;/p&gt;


&lt;h1&gt;
  
  
  1. Password Hashing Flow in a Node.js Application
&lt;/h1&gt;

&lt;p&gt;A secure authentication system follows this flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Registration
        |
        |
        v
User enters password
        |
        |
        v
Generate random salt
        |
        |
        v
Password Hashing Algorithm
        |
        |
        v
Store Hash in Database
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9bznzpygfe1awnd8mgct.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9bznzpygfe1awnd8mgct.png" alt="hashing" width="799" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"$argon2id$v=19$m=65536,t=3,p=4$..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During login:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Login
     |
     |
     v
Enter Password
     |
     |
     v
Retrieve Stored Hash
     |
     |
     v
Verify Password
     |
     |
     v
Allow / Reject Login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  2. Argon2id Implementation in Node.js
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What is Argon2id?
&lt;/h2&gt;

&lt;p&gt;Argon2id is currently the recommended password hashing algorithm for new applications.&lt;/p&gt;

&lt;p&gt;It was designed to resist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GPU cracking attacks&lt;/li&gt;
&lt;li&gt;Password dictionary attacks&lt;/li&gt;
&lt;li&gt;Large-scale offline attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike bcrypt and PBKDF2, Argon2id is &lt;strong&gt;memory-hard&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That means an attacker cannot simply add more GPUs to increase cracking speed.&lt;/p&gt;

&lt;h2&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5vgxowpou0fi40xtf2xl.png" alt="argon2" width="799" height="436"&gt;
&lt;/h2&gt;

&lt;h1&gt;
  
  
  Installing Argon2
&lt;/h1&gt;

&lt;p&gt;Install the package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;argon2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Basic Argon2id Password Hashing
&lt;/h1&gt;

&lt;p&gt;Example:&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;argon2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;argon2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hashPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;argon2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;argon2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argon2id&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;hash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;verifyPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;argon2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;password&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Argon2id Configuration
&lt;/h1&gt;

&lt;p&gt;Production systems should configure the cost parameters.&lt;/p&gt;

&lt;p&gt;Example:&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;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;argon2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,{&lt;/span&gt;

    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;argon2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argon2id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="na"&gt;memoryCost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;65536&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="na"&gt;timeCost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="na"&gt;parallelism&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;

&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F438k6vergceujhix8qmp.png" alt="argon2conf" width="799" height="436"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Understanding Argon2 Settings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  memoryCost
&lt;/h3&gt;

&lt;p&gt;Controls RAM usage.&lt;/p&gt;

&lt;p&gt;Example:&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;memoryCost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;65536&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;65536 KB

≈

64 MB RAM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Higher value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;More security
+
More server memory usage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  timeCost
&lt;/h3&gt;

&lt;p&gt;Number of iterations.&lt;/p&gt;

&lt;p&gt;Example:&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;timeCost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Password processing happens 3 times
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  parallelism
&lt;/h3&gt;

&lt;p&gt;Number of CPU threads.&lt;/p&gt;

&lt;p&gt;Example:&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;parallelism&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use 4 parallel lanes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Recommended Node.js Production Config
&lt;/h1&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;ARGON_CONFIG&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;argon2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argon2id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="na"&gt;memoryCost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;65536&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="na"&gt;timeCost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

    &lt;span class="na"&gt;parallelism&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;

&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Complete User Registration Example
&lt;/h1&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;argon2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;argon2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;registerUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;passwordHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;argon2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;ARGON_CONFIG&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;

        &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;passwordHash&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;Database stores:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$argon2id$v=19$m=65536,t=3,p=4$...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The configuration is stored inside the hash.&lt;/p&gt;

&lt;p&gt;You do not need to save:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;memoryCost
timeCost
parallelism
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;separately.&lt;/p&gt;




&lt;h1&gt;
  
  
  Login Verification
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;storedHash&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;valid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;argon2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;storedHash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;password&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;


    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;valid&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Login success&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;


    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Invalid password&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;h1&gt;
  
  
  3. bcrypt Implementation in Node.js
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What is bcrypt?
&lt;/h2&gt;

&lt;p&gt;bcrypt is one of the oldest and most widely used password hashing algorithms.&lt;/p&gt;

&lt;p&gt;It is still secure when configured correctly.&lt;/p&gt;

&lt;p&gt;Many existing Node.js applications use bcrypt.&lt;/p&gt;




&lt;h1&gt;
  
  
  Installing bcrypt
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;bcrypt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Basic bcrypt Example
&lt;/h1&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;bcrypt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bcrypt&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hashPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saltRounds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;saltRounds&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;h1&gt;
  
  
  Understanding bcrypt Cost Factor
&lt;/h1&gt;

&lt;p&gt;Example:&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;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is the cost factor.&lt;/p&gt;

&lt;p&gt;Calculation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2^cost
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cost 10

=
1024 rounds


cost 12

=
4096 rounds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Higher cost:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;More secure
+
Slower login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdu6dp9xyyxi1n26dmc6t.png" alt="costfactor" width="799" height="436"&gt;
&lt;/h2&gt;

&lt;h1&gt;
  
  
  Recommended bcrypt Configuration
&lt;/h1&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;BCRYPT_ROUNDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For high-security applications:&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;BCRYPT_ROUNDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  bcrypt Verification
&lt;/h1&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;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;userPassword&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;databaseHash&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;match&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;Authenticated&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;h1&gt;
  
  
  bcrypt Limitations
&lt;/h1&gt;

&lt;p&gt;bcrypt has one major limitation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Maximum password length:

72 bytes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VeryLongPassword....................

Only first 72 bytes processed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For new systems, Argon2id is usually preferred.&lt;/p&gt;




&lt;h1&gt;
  
  
  4. PBKDF2 Implementation in Node.js
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What is PBKDF2?
&lt;/h2&gt;

&lt;p&gt;PBKDF2 is a password-based key derivation algorithm.&lt;/p&gt;

&lt;p&gt;It is commonly used in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enterprise systems&lt;/li&gt;
&lt;li&gt;Banking systems&lt;/li&gt;
&lt;li&gt;Compliance environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Node.js already includes PBKDF2 through the built-in crypto module.&lt;/p&gt;

&lt;p&gt;No package installation required.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxy1l4er8l9gawnla2pdo.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxy1l4er8l9gawnla2pdo.png" alt="PBKDF2" width="799" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  PBKDF2 Example
&lt;/h1&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;crypto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;crypto&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hashPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;salt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomBytes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&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;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pbkdf2Sync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;

        &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="mi"&gt;600000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sha256&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="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="na"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;hash&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  PBKDF2 Configuration
&lt;/h1&gt;



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

&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="nx"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="nx"&gt;keyLength&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="nx"&gt;digest&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Example:&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="mi"&gt;600000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;600,000 iterations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Recommended PBKDF2 Settings
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="nl"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;600000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="nx"&gt;keyLength&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="nx"&gt;algorithm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sha256&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;h1&gt;
  
  
  PBKDF2 Verification
&lt;/h1&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;verifyPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nx"&gt;storedHash&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;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pbkdf2Sync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;

&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="mi"&gt;600000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sha256&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="nx"&gt;hash&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;===&lt;/span&gt;
&lt;span class="nx"&gt;storedHash&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;h1&gt;
  
  
  5. Node.js Configuration Comparison
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Algorithm&lt;/th&gt;
&lt;th&gt;Package&lt;/th&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Argon2id&lt;/td&gt;
&lt;td&gt;argon2&lt;/td&gt;
&lt;td&gt;memory, iterations, parallelism&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;bcrypt&lt;/td&gt;
&lt;td&gt;bcrypt&lt;/td&gt;
&lt;td&gt;salt rounds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PBKDF2&lt;/td&gt;
&lt;td&gt;crypto&lt;/td&gt;
&lt;td&gt;iterations, key length&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo4epy2gn2p5vdon3emna.png" alt="compare" width="799" height="436"&gt;
&lt;/h2&gt;

&lt;h1&gt;
  
  
  6. Environment-Based Configuration
&lt;/h1&gt;

&lt;p&gt;Do not hardcode security settings.&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;.env&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PASSWORD_ALGORITHM=argon2id

ARGON_MEMORY=65536
ARGON_TIME=3
ARGON_PARALLELISM=4

BCRYPT_ROUNDS=12

PBKDF2_ITERATIONS=600000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Configuration file:&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;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="na"&gt;argon2&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
&lt;span class="na"&gt;memoryCost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ARGON_MEMORY&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

&lt;span class="na"&gt;timeCost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ARGON_TIME&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;

&lt;span class="na"&gt;parallelism&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ARGON_PARALLELISM&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;},&lt;/span&gt;


&lt;span class="na"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;:{&lt;/span&gt;
&lt;span class="na"&gt;rounds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BCRYPT_ROUNDS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  7. Migrating bcrypt Users to Argon2id
&lt;/h1&gt;

&lt;p&gt;You don't need to reset every password.&lt;/p&gt;

&lt;p&gt;Migration flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Login

      |

Check bcrypt hash

      |

Password correct?

      |

Generate Argon2id hash

      |

Replace old hash

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

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt;


&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newHash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;argon2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="nx"&gt;ARGON_CONFIG&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;


&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;newHash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&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;Migration happens automatically.&lt;/p&gt;

&lt;h2&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpoonps1d5n7islszqymt.png" alt="migration" width="799" height="436"&gt;
&lt;/h2&gt;

&lt;h1&gt;
  
  
  8. Final Recommendation for Node.js Developers in 2026
&lt;/h1&gt;

&lt;h2&gt;
  
  
  New Projects
&lt;/h2&gt;

&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Argon2id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node.js
+
Express
+
PostgreSQL/MongoDB
+
Argon2id
+
JWT/Session
+
MFA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Existing Applications
&lt;/h2&gt;

&lt;p&gt;If you already use bcrypt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Keep bcrypt

+

Increase cost factor

+

Gradually migrate to Argon2id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Enterprise Applications
&lt;/h2&gt;

&lt;p&gt;If compliance requires it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PBKDF2-HMAC-SHA256
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Final Security Checklist
&lt;/h1&gt;

&lt;p&gt;A production authentication system should have:&lt;/p&gt;

&lt;p&gt;✅ Argon2id/bcrypt/PBKDF2&lt;br&gt;
✅ Unique salt per password&lt;br&gt;
✅ Rate limiting&lt;br&gt;
✅ Account lockout protection&lt;br&gt;
✅ MFA support&lt;br&gt;
✅ Password breach detection&lt;br&gt;
✅ Secure session management&lt;br&gt;
✅ HTTPS everywhere&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyjow3lgr4enmj6hbz0qq.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyjow3lgr4enmj6hbz0qq.png" alt="final" width="799" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;For Node.js applications in 2026:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Argon2id is the default choice for new systems.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;bcrypt remains reliable for existing applications, while PBKDF2 continues to be useful where compliance standards require it.&lt;/p&gt;

&lt;p&gt;The best implementation is not only choosing a strong hashing algorithm but also correctly configuring it, monitoring performance, and combining it with other authentication security layers.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>What 24 Hours of Non-Stop Coding Taught Me About Being a Developer</title>
      <dc:creator>Dulaj Thiwanka</dc:creator>
      <pubDate>Sat, 04 Apr 2026 17:05:58 +0000</pubDate>
      <link>https://dev.to/dthiwanka/what-24-hours-of-non-stop-coding-taught-me-about-being-a-developer-2jmk</link>
      <guid>https://dev.to/dthiwanka/what-24-hours-of-non-stop-coding-taught-me-about-being-a-developer-2jmk</guid>
      <description>&lt;p&gt;I Tried Building a Full App in 24 Hours… and It Was Way Harder Than I Expected&lt;/p&gt;

&lt;p&gt;I’ve started more projects than I can count.&lt;/p&gt;

&lt;p&gt;Some had amazing ideas.&lt;br&gt;
Some had clean designs.&lt;br&gt;
Some even had “this could actually work” potential.&lt;/p&gt;

&lt;p&gt;But most of them had one thing in common:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;They were never finished.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And if you’re a developer, you probably know this feeling a little too well.&lt;/p&gt;

&lt;p&gt;You start strong.&lt;br&gt;
You feel motivated.&lt;br&gt;
You imagine the final product.&lt;/p&gt;

&lt;p&gt;Then slowly…&lt;/p&gt;

&lt;p&gt;You get stuck.&lt;br&gt;
You overthink.&lt;br&gt;
You tweak things that don’t matter.&lt;br&gt;
And eventually, the project just… dies.&lt;/p&gt;

&lt;p&gt;No deadline. No pressure. No urgency.&lt;/p&gt;

&lt;p&gt;Just another unfinished folder sitting on your laptop.&lt;/p&gt;



&lt;p&gt;So one day, I decided to break that pattern.&lt;/p&gt;

&lt;p&gt;Not by learning more.&lt;br&gt;
Not by watching another tutorial.&lt;/p&gt;

&lt;p&gt;But by forcing myself into a corner.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fih4kvt13u1azgc2c1wni.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%2Fih4kvt13u1azgc2c1wni.png" alt="24hours" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
I gave myself exactly 24 hours.&lt;/p&gt;

&lt;p&gt;Not “over the weekend.”&lt;br&gt;
Not “whenever I have time.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;24 real, continuous hours.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And the goal was simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Build a complete full-stack app. Start to finish.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backend working&lt;/li&gt;
&lt;li&gt;Frontend working&lt;/li&gt;
&lt;li&gt;Database connected&lt;/li&gt;
&lt;li&gt;Everything integrated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No fake demos. No half-built features.&lt;/p&gt;

&lt;p&gt;Just something real.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Stack (No Time to Experiment)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdr1bsoynk83adgqfwl3l.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%2Fdr1bsoynk83adgqfwl3l.png" alt="stack" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I didn’t want to waste time choosing tools, so I stuck to what I already knew:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React + Tailwind for the frontend&lt;/li&gt;
&lt;li&gt;Node.js + Express for the backend&lt;/li&gt;
&lt;li&gt;MySQL with Sequelize&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This wasn’t about learning new tech.&lt;/p&gt;

&lt;p&gt;This was about &lt;strong&gt;execution under pressure&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Hour 1–2: The Most Dangerous Phase
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwk1ar4zk77usokl14i9g.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%2Fwk1ar4zk77usokl14i9g.png" alt="dangor" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This part almost ruined everything.&lt;/p&gt;

&lt;p&gt;I wasn’t coding yet.&lt;/p&gt;

&lt;p&gt;I was thinking.&lt;/p&gt;

&lt;p&gt;And thinking.&lt;/p&gt;

&lt;p&gt;And thinking.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Maybe I should build something unique…”&lt;/li&gt;
&lt;li&gt;“What if I add authentication?”&lt;/li&gt;
&lt;li&gt;“Should I make it scalable?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It sounds productive.&lt;/p&gt;

&lt;p&gt;But it’s actually a trap.&lt;/p&gt;

&lt;p&gt;Because the more you think, the bigger the project becomes.&lt;/p&gt;

&lt;p&gt;And the bigger the project becomes…&lt;/p&gt;

&lt;p&gt;The less likely you are to finish.&lt;/p&gt;



&lt;p&gt;Eventually, I forced myself to stop.&lt;/p&gt;

&lt;p&gt;No more ideas. No more upgrades.&lt;/p&gt;

&lt;p&gt;I picked something simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A basic task manager&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create. Update. Delete.&lt;/p&gt;

&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;No login system. No complex features.&lt;/p&gt;

&lt;p&gt;And honestly?&lt;/p&gt;

&lt;p&gt;That single decision was the reason I didn’t fail.&lt;/p&gt;


&lt;h2&gt;
  
  
  Hour 3–8: Backend Flow State
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcarrx65frcov1lrzvgb.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%2Frcarrx65frcov1lrzvgb.png" alt="bckend" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was probably the smoothest part of the entire challenge.&lt;/p&gt;

&lt;p&gt;I set up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Express server&lt;/li&gt;
&lt;li&gt;API routes&lt;/li&gt;
&lt;li&gt;Sequelize models&lt;/li&gt;
&lt;li&gt;Database connection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Basic endpoints:&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;POST&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;
&lt;span class="nx"&gt;GET&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;
&lt;span class="nx"&gt;PUT&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
&lt;span class="nx"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything felt… under control.&lt;/p&gt;

&lt;p&gt;No major bugs. No confusion.&lt;/p&gt;

&lt;p&gt;I was in that “flow state” where things just click.&lt;/p&gt;

&lt;p&gt;And for a moment, I genuinely thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I might actually finish this early.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Looking back, that was very optimistic &lt;/p&gt;




&lt;h2&gt;
  
  
  Hour 9–16: Where Everything Started Slipping
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5tptqzgibnsnm73wy66a.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%2F5tptqzgibnsnm73wy66a.png" alt="slip" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
Frontend always looks easier than it actually is.&lt;/p&gt;

&lt;p&gt;You think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“It’s just UI.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Until you start building it.&lt;/p&gt;




&lt;p&gt;At first, it was fine.&lt;/p&gt;

&lt;p&gt;I created components.&lt;br&gt;
Styled with Tailwind.&lt;br&gt;
Connected the API.&lt;/p&gt;

&lt;p&gt;Then things started breaking.&lt;/p&gt;

&lt;p&gt;Slowly.&lt;/p&gt;

&lt;p&gt;Then all at once.&lt;/p&gt;




&lt;p&gt;I ran into issues like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;State not updating correctly&lt;/li&gt;
&lt;li&gt;API calls returning unexpected data&lt;/li&gt;
&lt;li&gt;UI showing stale information&lt;/li&gt;
&lt;li&gt;Components re-rendering in weird ways&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At one point:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The database updated correctly… but the UI didn’t reflect it&lt;/li&gt;
&lt;li&gt;Then I fixed the UI… and broke the API connection&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It felt like a loop.&lt;/p&gt;

&lt;p&gt;Fix one thing → break another.&lt;/p&gt;




&lt;p&gt;This is the part most tutorials don’t show.&lt;/p&gt;

&lt;p&gt;Because this is where real development happens.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hour 17–22: The Mental Wall
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7q0eee8pzk4c48dobfjx.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%2F7q0eee8pzk4c48dobfjx.png" alt="mental" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
This was the hardest phase.&lt;/p&gt;

&lt;p&gt;Not because of complexity.&lt;/p&gt;

&lt;p&gt;But because of &lt;strong&gt;fatigue&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;After ~15 hours, your brain just slows down.&lt;/p&gt;

&lt;p&gt;Simple bugs take longer to understand.&lt;br&gt;
You reread the same code multiple times.&lt;br&gt;
You start making small mistakes.&lt;/p&gt;

&lt;p&gt;And then…&lt;/p&gt;

&lt;p&gt;💥 CORS issues&lt;br&gt;
💥 Endpoint mismatches&lt;br&gt;
💥 Random errors that didn’t exist before&lt;/p&gt;

&lt;p&gt;At one point I just stared at the screen thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Why is this even happening?”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;This is where most projects die.&lt;/p&gt;

&lt;p&gt;Not because they’re impossible.&lt;/p&gt;

&lt;p&gt;But because the developer gives up.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hour 23: A Shift in Mindset
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29b1f5kjfk0f9z33kl8o.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%2F29b1f5kjfk0f9z33kl8o.png" alt="shift" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
Something changed here.&lt;/p&gt;

&lt;p&gt;I stopped trying to make things “good.”&lt;/p&gt;

&lt;p&gt;And started trying to make things &lt;strong&gt;work&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;I asked myself:&lt;/p&gt;

&lt;p&gt;“What is the minimum required for this app to function?”&lt;/p&gt;

&lt;p&gt;And then I cut everything else.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No extra features&lt;/li&gt;
&lt;li&gt;No refactoring&lt;/li&gt;
&lt;li&gt;No polishing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Just core functionality.&lt;/p&gt;




&lt;p&gt;This was the turning point.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hour 24: Done… Not Perfect, But Done
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Finm24un39b9lliri62l4.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%2Finm24un39b9lliri62l4.png" alt="done" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
And finally…&lt;/p&gt;

&lt;p&gt;It worked.&lt;/p&gt;




&lt;p&gt;Was it clean?&lt;br&gt;
Not really.&lt;/p&gt;

&lt;p&gt;Was it scalable?&lt;br&gt;
Definitely not.&lt;/p&gt;

&lt;p&gt;Was it something I’d proudly show in a portfolio?&lt;/p&gt;

&lt;p&gt;Probably no.&lt;/p&gt;




&lt;p&gt;But it was finished.&lt;/p&gt;

&lt;p&gt;And that felt different.&lt;/p&gt;

&lt;p&gt;Because finishing something under pressure hits in a way that slow projects don’t.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Final App
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F496027a4e9267jzz37i5.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%2F496027a4e9267jzz37i5.png" alt="finl" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simple and honest:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add tasks&lt;/li&gt;
&lt;li&gt;Edit tasks&lt;/li&gt;
&lt;li&gt;Delete tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;No authentication.&lt;br&gt;
No animations.&lt;br&gt;
No “cool features.”&lt;/p&gt;

&lt;p&gt;Just a working product.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Actually Taught Me
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnzgf9mbsscd4jylpp2xj.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%2Fnzgf9mbsscd4jylpp2xj.png" alt="tauht" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This wasn’t just a coding challenge.&lt;/p&gt;

&lt;p&gt;It exposed how I work.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. I Overthink Way More Than I Realize
&lt;/h3&gt;

&lt;p&gt;Most of my delays weren’t technical.&lt;/p&gt;

&lt;p&gt;They were mental.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Simplicity Is Not “Basic” — It’s Strategic
&lt;/h3&gt;

&lt;p&gt;The smaller the scope, the higher the success rate.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Perfection Is Just a Delay Mechanism
&lt;/h3&gt;

&lt;p&gt;Trying to make things perfect almost made me fail completely.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Execution Is a Skill
&lt;/h3&gt;

&lt;p&gt;And like any skill, it improves under pressure.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Finishing Is Rare
&lt;/h3&gt;

&lt;p&gt;Starting is easy.&lt;/p&gt;

&lt;p&gt;Planning is easy.&lt;/p&gt;

&lt;p&gt;Learning is easy.&lt;/p&gt;

&lt;p&gt;But finishing?&lt;/p&gt;

&lt;p&gt;That’s what separates people.&lt;/p&gt;




&lt;h2&gt;
  
  
  Would I Do It Again? 🤔
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftjdub76kn3txgfddtpeb.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%2Ftjdub76kn3txgfddtpeb.png" alt="do" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;p&gt;But smarter.&lt;/p&gt;




&lt;p&gt;Next time I would:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Define scope faster&lt;/li&gt;
&lt;li&gt;Cut features earlier&lt;/li&gt;
&lt;li&gt;Focus only on what matters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because this challenge isn’t about building something impressive.&lt;/p&gt;




&lt;p&gt;It’s about proving one thing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;You can finish what you start.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  If You’re Still Reading…
&lt;/h2&gt;

&lt;p&gt;Try this.&lt;/p&gt;

&lt;p&gt;Seriously.&lt;/p&gt;

&lt;p&gt;Give yourself 24 hours.&lt;/p&gt;

&lt;p&gt;No extensions. No excuses.&lt;/p&gt;

&lt;p&gt;Build something.&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%2F3lk8d9g21dqzvaenpkki.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%2F3lk8d9g21dqzvaenpkki.png" alt="build" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And when you’re done, ask yourself:&lt;/p&gt;

&lt;p&gt;“Did I actually finish… or did I overthink again?”&lt;/p&gt;

</description>
      <category>development</category>
      <category>fullstack</category>
      <category>devchallenge</category>
      <category>architecture</category>
    </item>
    <item>
      <title>The Ultimate Guide to Browser Storage: LocalStorage, IndexedDB, Cookies, and More</title>
      <dc:creator>Dulaj Thiwanka</dc:creator>
      <pubDate>Thu, 12 Mar 2026 08:02:04 +0000</pubDate>
      <link>https://dev.to/dthiwanka/the-ultimate-guide-to-browser-storage-localstorage-indexeddb-cookies-and-more-4g6l</link>
      <guid>https://dev.to/dthiwanka/the-ultimate-guide-to-browser-storage-localstorage-indexeddb-cookies-and-more-4g6l</guid>
      <description>&lt;p&gt;Modern browsers have evolved far beyond simple document viewers. Today they function almost like miniature operating systems running inside your computer. They manage memory, execute applications, cache resources, and even host databases.&lt;/p&gt;

&lt;p&gt;One of the most powerful capabilities browsers provide is &lt;strong&gt;client-side storage&lt;/strong&gt; the ability to store data directly on the user’s device.&lt;/p&gt;

&lt;p&gt;Client-side storage allows web applications to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce server requests&lt;/li&gt;
&lt;li&gt;Improve performance&lt;/li&gt;
&lt;li&gt;Persist user preferences&lt;/li&gt;
&lt;li&gt;Enable offline experiences&lt;/li&gt;
&lt;li&gt;Cache network resources&lt;/li&gt;
&lt;li&gt;Store complex application data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without browser storage, modern web applications like Gmail, Notion, Spotify Web, and Figma would be significantly slower and far less capable.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore the most important browser storage mechanisms available today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Local Storage&lt;/li&gt;
&lt;li&gt;Session Storage&lt;/li&gt;
&lt;li&gt;Extension Storage&lt;/li&gt;
&lt;li&gt;IndexedDB&lt;/li&gt;
&lt;li&gt;Cookies&lt;/li&gt;
&lt;li&gt;Cache Storage&lt;/li&gt;
&lt;li&gt;Storage Buckets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding these systems helps developers choose the right tool for each type of data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fol28wgzib9mc5j1xo0cm.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%2Fol28wgzib9mc5j1xo0cm.png" alt="alltyps"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Browser Storage Exists
&lt;/h2&gt;

&lt;p&gt;Before diving into each storage system, it’s helpful to understand &lt;strong&gt;why browsers need storage mechanisms in the first place&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Early web applications relied entirely on servers. Every user action required a network request, and every piece of state lived on the server.&lt;/p&gt;

&lt;p&gt;This approach had several problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;High latency&lt;/li&gt;
&lt;li&gt;Server overload&lt;/li&gt;
&lt;li&gt;No offline capability&lt;/li&gt;
&lt;li&gt;Poor user experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Client-side storage solves these issues by allowing applications to store data locally.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A theme preference can be stored locally instead of requested every time.&lt;/li&gt;
&lt;li&gt;Cached assets can load instantly without network requests.&lt;/li&gt;
&lt;li&gt;Entire applications can function offline.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Modern browsers therefore provide multiple storage systems designed for different types of data.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Local Storage
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1e8auvof8s2fnnz1q9sg.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%2F1e8auvof8s2fnnz1q9sg.png" alt="local"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Local Storage is the most widely known browser storage API. It provides a simple way to store &lt;strong&gt;persistent key–value data&lt;/strong&gt; inside the browser.&lt;/p&gt;

&lt;p&gt;The stored data remains available even after:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Page reloads&lt;/li&gt;
&lt;li&gt;Browser restarts&lt;/li&gt;
&lt;li&gt;System restarts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This makes Local Storage ideal for storing small pieces of persistent application state.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Characteristics&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Key–value storage&lt;/li&gt;
&lt;li&gt;Stores &lt;strong&gt;strings only&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Persistent across sessions&lt;/li&gt;
&lt;li&gt;Around &lt;strong&gt;5–10 MB per origin&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Synchronous API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The synchronous nature means Local Storage operations block the main thread, which is why it should only be used for small data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Save data&lt;/span&gt;
&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;username&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;dulaj&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Retrieve data&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;username&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Remove item&lt;/span&gt;
&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;username&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Clear all data&lt;/span&gt;
&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since Local Storage only stores strings, objects must be serialized using JSON.&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Dulaj&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storedUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&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;h2&gt;
  
  
  Storage Scope
&lt;/h2&gt;

&lt;p&gt;Local Storage is scoped by &lt;strong&gt;origin&lt;/strong&gt;, which means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;protocol + domain + port
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;https://example.com
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A different subdomain or port creates a different storage space.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Use Cases
&lt;/h2&gt;

&lt;p&gt;Local Storage is commonly used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI preferences&lt;/li&gt;
&lt;li&gt;Theme settings&lt;/li&gt;
&lt;li&gt;Language configuration&lt;/li&gt;
&lt;li&gt;Feature flags&lt;/li&gt;
&lt;li&gt;Remembering user interface states&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, Local Storage is &lt;strong&gt;not suitable for large datasets or high-frequency operations&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Session Storage
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F26q9zn0hhplu28rm45is.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%2F26q9zn0hhplu28rm45is.png" alt="session"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Session Storage is extremely similar to Local Storage but with a shorter lifespan.&lt;/p&gt;

&lt;p&gt;Instead of persisting across browser restarts, Session Storage exists only during the &lt;strong&gt;lifetime of a browser tab&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once the tab closes, the stored data is permanently deleted.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Characteristics&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Key–value storage&lt;/li&gt;
&lt;li&gt;Stores strings&lt;/li&gt;
&lt;li&gt;Scoped per &lt;strong&gt;tab session&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Around &lt;strong&gt;5 MB capacity&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Synchronous API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each tab has its own isolated session storage, meaning two tabs from the same website do not share session data.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Example&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;step&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;2&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;step&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sessionStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;step&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Use Cases&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Session Storage is useful when the stored data should not persist permanently.&lt;/p&gt;

&lt;p&gt;Examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multi-step form progress&lt;/li&gt;
&lt;li&gt;Temporary UI states&lt;/li&gt;
&lt;li&gt;Checkout process data&lt;/li&gt;
&lt;li&gt;Navigation history state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the user refreshes the page, the data remains. If the tab closes, the data disappears.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Extension Storage
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F204gpyo88hpzndlb8fpf.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%2F204gpyo88hpzndlb8fpf.png" alt="extenstion"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Browser extensions operate in a different environment than normal web pages. Because of this, browsers provide a dedicated &lt;strong&gt;Extension Storage API&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This API allows extensions to store configuration data, cached content, and synced settings.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Types of Extension Storage&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Most browsers support three storage types:&lt;/p&gt;

&lt;h3&gt;
  
  
  storage.local
&lt;/h3&gt;

&lt;p&gt;Stores data locally on the user's device.&lt;/p&gt;

&lt;h3&gt;
  
  
  storage.sync
&lt;/h3&gt;

&lt;p&gt;Synchronizes data across devices using the browser account.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chrome sync&lt;/li&gt;
&lt;li&gt;Firefox sync&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  storage.session
&lt;/h3&gt;

&lt;p&gt;Temporary storage for the extension session.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&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;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;chrome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;theme&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;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;theme&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;Unlike Local Storage, Extension Storage APIs are &lt;strong&gt;asynchronous&lt;/strong&gt;, making them more suitable for larger data operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Use Cases
&lt;/h2&gt;

&lt;p&gt;Extensions use storage for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User settings&lt;/li&gt;
&lt;li&gt;Feature toggles&lt;/li&gt;
&lt;li&gt;Cached extension data&lt;/li&gt;
&lt;li&gt;Syncing configuration across devices&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. IndexedDB
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftcc2zuf8db98qgptz33t.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%2Ftcc2zuf8db98qgptz33t.png" alt="indexdb"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When developers need to store large amounts of structured data, &lt;strong&gt;IndexedDB&lt;/strong&gt; becomes the primary solution.&lt;/p&gt;

&lt;p&gt;IndexedDB is a &lt;strong&gt;transactional NoSQL database built directly into the browser&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It allows developers to store complex data such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Objects&lt;/li&gt;
&lt;li&gt;Files&lt;/li&gt;
&lt;li&gt;Blobs&lt;/li&gt;
&lt;li&gt;Structured datasets&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Concepts
&lt;/h2&gt;

&lt;p&gt;IndexedDB introduces several database concepts:&lt;/p&gt;

&lt;h3&gt;
  
  
  Database
&lt;/h3&gt;

&lt;p&gt;The top-level container for stored data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Object Store
&lt;/h3&gt;

&lt;p&gt;Similar to tables in relational databases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Index
&lt;/h3&gt;

&lt;p&gt;Allows fast lookup of records.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transaction
&lt;/h3&gt;

&lt;p&gt;Ensures safe and consistent database operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&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;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;indexedDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;AppDatabase&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onupgradeneeded&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;db&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;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;store&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users&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;keyPath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;store&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&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;email&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;unique&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once created, the database can store large volumes of structured data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages
&lt;/h2&gt;

&lt;p&gt;IndexedDB provides several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asynchronous API&lt;/li&gt;
&lt;li&gt;Large storage capacity&lt;/li&gt;
&lt;li&gt;Efficient querying through indexes&lt;/li&gt;
&lt;li&gt;Offline functionality&lt;/li&gt;
&lt;li&gt;Structured data storage&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-World Usage
&lt;/h2&gt;

&lt;p&gt;Many major applications rely on IndexedDB:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gmail (offline email storage)&lt;/li&gt;
&lt;li&gt;Google Docs&lt;/li&gt;
&lt;li&gt;Notion&lt;/li&gt;
&lt;li&gt;Figma&lt;/li&gt;
&lt;li&gt;Progressive Web Apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;IndexedDB allows web apps to behave much more like native applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Cookies
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzh8tfzzrvi3jyjq6zeq.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%2Fhzh8tfzzrvi3jyjq6zeq.png" alt="cookies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cookies are the &lt;strong&gt;oldest form of browser storage&lt;/strong&gt;, originally designed to maintain state across HTTP requests.&lt;/p&gt;

&lt;p&gt;HTTP itself is stateless, meaning each request is independent. Cookies solve this by storing small pieces of data that the browser automatically sends with each request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Characteristics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Maximum size: &lt;strong&gt;~4 KB&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Automatically included in HTTP requests&lt;/li&gt;
&lt;li&gt;Can have expiration times&lt;/li&gt;
&lt;li&gt;Supports security flags&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cookie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;theme=dark; path=/; expires=Fri, 31 Dec 2026 12:00:00 UTC&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;h2&gt;
  
  
  Security Flags
&lt;/h2&gt;

&lt;p&gt;Cookies can be configured with additional security options.&lt;/p&gt;

&lt;h3&gt;
  
  
  HttpOnly
&lt;/h3&gt;

&lt;p&gt;Prevents JavaScript access.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secure
&lt;/h3&gt;

&lt;p&gt;Only sent over HTTPS.&lt;/p&gt;

&lt;h3&gt;
  
  
  SameSite
&lt;/h3&gt;

&lt;p&gt;Controls cross-site request behavior.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;Set-Cookie: sessionId=abc123; Secure; HttpOnly; SameSite=Strict
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Use Cases
&lt;/h2&gt;

&lt;p&gt;Cookies are commonly used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication sessions&lt;/li&gt;
&lt;li&gt;Tracking identifiers&lt;/li&gt;
&lt;li&gt;Personalization&lt;/li&gt;
&lt;li&gt;Server-side preferences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because cookies are included with every request, they should contain minimal data.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Cache Storage
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv3w3pjdvksh9f8vpmifl.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%2Fv3w3pjdvksh9f8vpmifl.png" alt="cache"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cache Storage is part of the &lt;strong&gt;Service Worker API&lt;/strong&gt; and is designed for storing network resources.&lt;/p&gt;

&lt;p&gt;Instead of storing arbitrary data, it stores &lt;strong&gt;HTTP request–response pairs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This enables developers to implement custom caching strategies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&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;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;caches&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;app-cache&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/index.html&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/styles.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/app.js&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;When a user visits the site again, the cached version can be served instantly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits
&lt;/h2&gt;

&lt;p&gt;Cache Storage enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Offline web applications&lt;/li&gt;
&lt;li&gt;Faster loading times&lt;/li&gt;
&lt;li&gt;Reduced server load&lt;/li&gt;
&lt;li&gt;Advanced caching strategies&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Common Strategies
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Cache First
&lt;/h3&gt;

&lt;p&gt;Use cache before network.&lt;/p&gt;

&lt;h3&gt;
  
  
  Network First
&lt;/h3&gt;

&lt;p&gt;Try network first, fallback to cache.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stale While Revalidate
&lt;/h3&gt;

&lt;p&gt;Serve cached version while fetching an updated version in the background.&lt;/p&gt;

&lt;p&gt;These strategies are widely used in &lt;strong&gt;Progressive Web Apps (PWAs)&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Storage Buckets
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2cj6ntdm6ml3051m5ozk.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%2F2cj6ntdm6ml3051m5ozk.png" alt="buckets"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Storage Buckets are a relatively new browser storage concept aimed at improving storage management.&lt;/p&gt;

&lt;p&gt;Instead of storing all application data in one shared space, developers can create &lt;strong&gt;separate logical buckets&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each bucket can have its own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lifetime&lt;/li&gt;
&lt;li&gt;Storage quota&lt;/li&gt;
&lt;li&gt;Eviction priority&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;App Storage
├── user-data
├── cache
└── temporary-files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the browser needs to free space, it can remove lower priority buckets first.&lt;/p&gt;

&lt;p&gt;This prevents critical application data from being deleted unexpectedly.&lt;/p&gt;

&lt;p&gt;Storage Buckets are still evolving but represent a major improvement in browser storage architecture.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comparison of Browser Storage Options
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Storage Type&lt;/th&gt;
&lt;th&gt;Persistence&lt;/th&gt;
&lt;th&gt;Capacity&lt;/th&gt;
&lt;th&gt;Data Type&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Local Storage&lt;/td&gt;
&lt;td&gt;Persistent&lt;/td&gt;
&lt;td&gt;~5–10 MB&lt;/td&gt;
&lt;td&gt;Strings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Session Storage&lt;/td&gt;
&lt;td&gt;Tab lifetime&lt;/td&gt;
&lt;td&gt;~5 MB&lt;/td&gt;
&lt;td&gt;Strings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cookies&lt;/td&gt;
&lt;td&gt;Configurable&lt;/td&gt;
&lt;td&gt;~4 KB&lt;/td&gt;
&lt;td&gt;Strings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IndexedDB&lt;/td&gt;
&lt;td&gt;Persistent&lt;/td&gt;
&lt;td&gt;Large&lt;/td&gt;
&lt;td&gt;Structured objects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cache Storage&lt;/td&gt;
&lt;td&gt;Persistent&lt;/td&gt;
&lt;td&gt;Large&lt;/td&gt;
&lt;td&gt;HTTP responses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Extension Storage&lt;/td&gt;
&lt;td&gt;Persistent&lt;/td&gt;
&lt;td&gt;Large&lt;/td&gt;
&lt;td&gt;JSON-like&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Storage Buckets&lt;/td&gt;
&lt;td&gt;Managed&lt;/td&gt;
&lt;td&gt;Large&lt;/td&gt;
&lt;td&gt;Multiple types&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  How Modern Web Apps Use Browser Storage
&lt;/h2&gt;

&lt;p&gt;Most production web applications combine multiple storage systems.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;A Progressive Web App might use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local Storage&lt;/strong&gt; for UI preferences&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IndexedDB&lt;/strong&gt; for large application data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache Storage&lt;/strong&gt; for offline assets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cookies&lt;/strong&gt; for authentication sessions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This layered storage architecture enables fast, responsive, and reliable web applications.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Browser storage has evolved dramatically over the past decade. What once started as simple cookies has grown into a complete ecosystem of storage technologies.&lt;/p&gt;

&lt;p&gt;Today, browsers provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Key–value storage&lt;/li&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;Network caches&lt;/li&gt;
&lt;li&gt;Offline storage systems&lt;/li&gt;
&lt;li&gt;Structured storage management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This capability allows web applications to behave increasingly like native desktop or mobile apps.&lt;/p&gt;

&lt;p&gt;Understanding how each storage system works — and when to use it — is a critical skill for modern web developers building scalable and high-performance applications.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>browser</category>
    </item>
    <item>
      <title>Git, Explained</title>
      <dc:creator>Dulaj Thiwanka</dc:creator>
      <pubDate>Tue, 03 Feb 2026 11:05:22 +0000</pubDate>
      <link>https://dev.to/dthiwanka/git-explained-1bkh</link>
      <guid>https://dev.to/dthiwanka/git-explained-1bkh</guid>
      <description>&lt;p&gt;Git is everywhere.&lt;br&gt;
Jobs expect it. Teams depend on it. Tutorials assume you already understand it.&lt;/p&gt;

&lt;p&gt;And yet, many developers use Git daily while secretly hoping nothing goes wrong.&lt;/p&gt;

&lt;p&gt;This article is not about memorizing commands.&lt;br&gt;
It’s about understanding &lt;strong&gt;what Git is thinking&lt;/strong&gt;, so the commands stop feeling dangerous.&lt;/p&gt;

&lt;p&gt;We’ll go slowly. Very slowly. On purpose.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 1: Why Git Exists (A Very Human Problem)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiaphpcu2a7a2cbd3cmiy.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%2Fiaphpcu2a7a2cbd3cmiy.png" alt="whygit" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Imagine writing a document over several weeks.&lt;/p&gt;

&lt;p&gt;You save versions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;report.docx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;report_final.docx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;report_final_v3_REAL.docx&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now imagine three people editing that document at the same time.&lt;/p&gt;

&lt;p&gt;That chaos is what Git was built to prevent.&lt;/p&gt;

&lt;p&gt;Git exists to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Track changes over time&lt;/li&gt;
&lt;li&gt;Let multiple people work safely&lt;/li&gt;
&lt;li&gt;Make mistakes reversible&lt;/li&gt;
&lt;li&gt;Preserve context (the &lt;em&gt;why&lt;/em&gt;, not just the &lt;em&gt;what&lt;/em&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Git is not just backup.&lt;br&gt;
Git is &lt;strong&gt;structured memory&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 2: The Mental Model That Changes Everything
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F33rzkps8ieef4stiy40h.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%2F33rzkps8ieef4stiy40h.png" alt="track" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s the idea that makes Git stop feeling random:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Git does &lt;strong&gt;not&lt;/strong&gt; track changes.&lt;br&gt;
Git tracks &lt;strong&gt;snapshots&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every commit is a photograph of your entire project folder at a specific moment in time.&lt;/p&gt;

&lt;p&gt;If a file hasn’t changed, Git doesn’t store it again.&lt;br&gt;
It simply points to the previous version.&lt;/p&gt;

&lt;p&gt;This is why:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Git is efficient&lt;/li&gt;
&lt;li&gt;Git is fast&lt;/li&gt;
&lt;li&gt;Git history feels immutable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once something is committed, it becomes a historical fact.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 3: Creating a Repository (Where Memory Begins)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsjnqejiiyba0cjutmdje.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%2Fsjnqejiiyba0cjutmdje.png" alt="git" width="400" height="169"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a hidden folder called &lt;code&gt;.git&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That folder contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every commit&lt;/li&gt;
&lt;li&gt;Every branch&lt;/li&gt;
&lt;li&gt;The entire history graph&lt;/li&gt;
&lt;li&gt;All metadata&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your code files are &lt;em&gt;outside&lt;/em&gt; &lt;code&gt;.git&lt;/code&gt;.&lt;br&gt;
Your project’s &lt;strong&gt;memory&lt;/strong&gt; lives &lt;em&gt;inside&lt;/em&gt; &lt;code&gt;.git&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;.git&lt;/code&gt; disappears, Git forgets everything.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 4: The Three Places Your Code Can Exist
&lt;/h2&gt;

&lt;p&gt;This is the most important concept in Git.&lt;br&gt;
If you understand this, almost everything else makes sense.&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%2F7r53n641ry3hjzd4dpm9.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%2F7r53n641ry3hjzd4dpm9.png" alt="image" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Working Directory
&lt;/h3&gt;

&lt;p&gt;This is your normal folder.&lt;br&gt;
You edit files here.&lt;br&gt;
Git is watching, but nothing is saved yet.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Staging Area (Index)
&lt;/h3&gt;

&lt;p&gt;This is where you tell Git:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“These specific changes are ready to be recorded.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not everything. Just what you choose.&lt;/p&gt;
&lt;h3&gt;
  
  
  3. Repository (Commits)
&lt;/h3&gt;

&lt;p&gt;This is Git’s permanent history.&lt;br&gt;
Once something is here, it’s part of the timeline.&lt;/p&gt;

&lt;p&gt;Git &lt;strong&gt;never commits directly&lt;/strong&gt; from your folder.&lt;br&gt;
It commits from the staging area—because intention matters.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 5: Asking Git What It Sees
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fofmcr9lf1o1t5el4dy97.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%2Fofmcr9lf1o1t5el4dy97.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before running any command, get used to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What changed&lt;/li&gt;
&lt;li&gt;What’s staged&lt;/li&gt;
&lt;li&gt;What’s not tracked&lt;/li&gt;
&lt;li&gt;What Git is waiting for&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If Git ever feels confusing, it’s usually because &lt;code&gt;git status&lt;/code&gt; wasn’t read.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 6: What &lt;code&gt;git add&lt;/code&gt; Really Does
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5e6ncuw1dxp8mmhuoii9.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%2F5e6ncuw1dxp8mmhuoii9.png" alt="image" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This does &lt;strong&gt;not&lt;/strong&gt; mean “save forever”.&lt;/p&gt;

&lt;p&gt;It means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Take the current version of this file and copy it into the staging area.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can still edit the file afterward.&lt;br&gt;
The staged version will not change unless you add it again.&lt;/p&gt;

&lt;p&gt;This lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stage only part of your work&lt;/li&gt;
&lt;li&gt;Create clean, focused commits&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Part 7: Committing (Freezing a Moment)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ba5rmusecu52x614ofd.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%2F7ba5rmusecu52x614ofd.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add homepage layout"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A snapshot&lt;/li&gt;
&lt;li&gt;A unique hash (ID)&lt;/li&gt;
&lt;li&gt;A permanent history point&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Commits cannot be edited.&lt;br&gt;
Git does not erase history—it adds to it.&lt;/p&gt;

&lt;p&gt;Think of commits as pages in a journal.&lt;br&gt;
You don’t rip out pages. You write new ones.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 8: Commit Messages Are for Humans
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq704olhf87vilmsw8h9c.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%2Fq704olhf87vilmsw8h9c.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bad messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fix
update
stuff
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good messages explain &lt;strong&gt;intent&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fix broken layout on small screens
Add input validation for signup form
Refactor auth logic to simplify flow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your future self will read this.&lt;br&gt;
So will teammates.&lt;br&gt;
Write like you’re explaining your thinking.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 9: Reading History Without Fear
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvv90rr09mybhpa3bqvi.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%2Fnvv90rr09mybhpa3bqvi.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt; &lt;span class="nt"&gt;--graph&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Commits as nodes&lt;/li&gt;
&lt;li&gt;Parent relationships&lt;/li&gt;
&lt;li&gt;Branch structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Git history is a &lt;strong&gt;graph&lt;/strong&gt;, not a straight line.&lt;br&gt;
That’s why merges and branches exist.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 10: Branches (The Safest Place to Experiment)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwwyb7np0nhlz8eoxlmx.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%2Fmwwyb7np0nhlz8eoxlmx.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A branch is &lt;strong&gt;not a copy of your code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A branch is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A movable label pointing to a commit&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s why creating branches is cheap and encouraged.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;-b&lt;/span&gt; feature/settings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;main&lt;/code&gt; stays stable&lt;/li&gt;
&lt;li&gt;Your work happens safely elsewhere&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each commit moves the branch pointer forward.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 11: HEAD (Git’s “You Are Here” Marker)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7t45f49dgyd85sv9wzx6.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%2F7t45f49dgyd85sv9wzx6.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;HEAD&lt;/code&gt; simply means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“This is where you are right now.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Usually it points to a branch.&lt;br&gt;
Sometimes it points directly to a commit.&lt;/p&gt;

&lt;p&gt;Most confusion comes from not knowing where HEAD is.&lt;/p&gt;

&lt;p&gt;When lost, ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What branch am I on?&lt;/li&gt;
&lt;li&gt;What commit does it point to?&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Part 12: Merging (Bringing Work Together)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fld4l6tlbr3wkj4sgnump.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%2Fld4l6tlbr3wkj4sgnump.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When a feature is ready:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout main
git merge feature/settings
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Git tries to combine histories.&lt;/p&gt;

&lt;p&gt;Two common outcomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fast-forward merge (simple pointer move)&lt;/li&gt;
&lt;li&gt;Merge commit (combining branches)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both are normal.&lt;br&gt;
History shape is a choice, not a mistake.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 13: Merge Conflicts (Not Errors)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa0ynoygheat0d1thkeky.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%2Fa0ynoygheat0d1thkeky.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A conflict means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Git can’t decide for you.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Git stops.&lt;br&gt;
Marks the file.&lt;br&gt;
Waits.&lt;/p&gt;

&lt;p&gt;You:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the file&lt;/li&gt;
&lt;li&gt;Choose what stays&lt;/li&gt;
&lt;li&gt;Remove conflict markers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conflicts are collaboration points, not failures.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 14: Working With Other Humans (Remotes)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F54qp638x2k6meg7ubdia.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%2F54qp638x2k6meg7ubdia.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A remote repository is just another copy of the same timeline.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;“I’m sharing my history.”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git fetch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;“Show me new history.”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git pull
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;“Combine their history with mine.”&lt;/p&gt;

&lt;p&gt;If you’re unsure, fetch first.&lt;br&gt;
Nothing breaks from fetching.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 15: Undoing Mistakes Calmly
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8d704oykw8mi7hve816.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%2Fk8d704oykw8mi7hve816.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Undo local file changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout &lt;span class="nt"&gt;--&lt;/span&gt; file.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Undo a commit safely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git revert &amp;lt;commit&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Revert creates a &lt;em&gt;new&lt;/em&gt; commit that cancels the old one.&lt;br&gt;
History remains truthful.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 16: Stashing (Hiding Work Temporarily)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7ppd5331uozwcxb1kzov.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%2F7ppd5331uozwcxb1kzov.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Git hides uncommitted changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git stash pop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Git restores them.&lt;/p&gt;

&lt;p&gt;Stash is for interruptions, not long-term storage.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 17: Rebase (Editing the Story)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fku5410rrs3ztof8u2wdu.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%2Fku5410rrs3ztof8u2wdu.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rebase rewrites commits so history looks clean and linear.&lt;/p&gt;

&lt;p&gt;Think of it as editing a draft before publishing.&lt;/p&gt;

&lt;p&gt;Golden rule:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Never rebase commits others already have&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Part 18: Interactive Rebase (Advanced Control)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fczjvs737lehv6zonfgw0.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%2Fczjvs737lehv6zonfgw0.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git rebase &lt;span class="nt"&gt;-i&lt;/span&gt; HEAD~5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Combine commits&lt;/li&gt;
&lt;li&gt;Rename messages&lt;/li&gt;
&lt;li&gt;Remove mistakes&lt;/li&gt;
&lt;li&gt;Reorder history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is how clean histories are made.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 19: Reflog (The Panic Button)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkjm833uwai4omj94p4wp.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%2Fkjm833uwai4omj94p4wp.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git reflog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Git remembers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every checkout&lt;/li&gt;
&lt;li&gt;Every reset&lt;/li&gt;
&lt;li&gt;Every mistake&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you think something is lost, reflog usually knows where it went.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 20: Habits That Make Git Pleasant
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsya50klouzqoglda2nwj.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%2Fsya50klouzqoglda2nwj.png" alt="Image" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Commit small changes&lt;/li&gt;
&lt;li&gt;Write clear messages&lt;/li&gt;
&lt;li&gt;Read &lt;code&gt;git status&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Don’t force-push shared branches&lt;/li&gt;
&lt;li&gt;Respect the timeline&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Git is strict, not cruel.&lt;/p&gt;

&lt;p&gt;It does exactly what you tell it to do.&lt;br&gt;
Nothing more.&lt;br&gt;
Nothing less.&lt;/p&gt;

&lt;p&gt;Once you understand snapshots, staging, and history, Git stops being scary and starts being dependable.&lt;/p&gt;

&lt;p&gt;And a dependable memory is one of the most powerful tools a developer can have.&lt;/p&gt;

&lt;p&gt;Keep committing.&lt;/p&gt;

</description>
      <category>git</category>
      <category>beginners</category>
      <category>explainlikeimfive</category>
      <category>programming</category>
    </item>
    <item>
      <title>Before I Write Any Code, I Do This First (A Practical Project Walkthrough)</title>
      <dc:creator>Dulaj Thiwanka</dc:creator>
      <pubDate>Mon, 26 Jan 2026 07:41:35 +0000</pubDate>
      <link>https://dev.to/dthiwanka/before-i-write-any-code-i-do-this-first-a-practical-project-walkthrough-5aaa</link>
      <guid>https://dev.to/dthiwanka/before-i-write-any-code-i-do-this-first-a-practical-project-walkthrough-5aaa</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%2Fkm7wqazqma2mrkti8rjk.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%2Fkm7wqazqma2mrkti8rjk.png" alt="Thinking" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most people believe software projects fail because of bad code.&lt;/p&gt;

&lt;p&gt;That’s rarely true.&lt;/p&gt;

&lt;p&gt;They fail because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The problem wasn’t clear&lt;/li&gt;
&lt;li&gt;The scope was too big&lt;/li&gt;
&lt;li&gt;Decisions were made too late&lt;/li&gt;
&lt;li&gt;Structure was an afterthought&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I used to jump straight into coding. It felt productive. It felt exciting.&lt;/p&gt;

&lt;p&gt;But I kept hitting the same wall:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rewriting things&lt;/li&gt;
&lt;li&gt;Adding features endlessly&lt;/li&gt;
&lt;li&gt;Losing motivation halfway&lt;/li&gt;
&lt;li&gt;Abandoning projects that &lt;em&gt;should&lt;/em&gt; have worked&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eventually, I realized something simple but uncomfortable:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If I’m confused while building, it’s because I was confused before I started.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So now, before I write &lt;strong&gt;any&lt;/strong&gt; code, I structure the project carefully. This article shows &lt;strong&gt;exactly how&lt;/strong&gt;, step by step, using a real project example—no tech background required.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Example Project We’ll Use
&lt;/h2&gt;

&lt;p&gt;To keep this real and relatable, let’s use a practical example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A very simple expense-tracking app&lt;/strong&gt;&lt;br&gt;
(Not a startup, not a “next big thing” — just something useful.)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This makes it easier to see how each step affects real decisions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: I Slow Down and Kill the “Build Something” Urge
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg8w11qveuqs612bzbewx.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%2Fg8w11qveuqs612bzbewx.png" alt="Defining the Problem" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first thing I do is &lt;strong&gt;nothing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No editor.&lt;br&gt;
No framework.&lt;br&gt;
No repo.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because excitement is dangerous. When you’re excited, you say yes to everything—and regret it later.&lt;/p&gt;

&lt;p&gt;Instead, I open a blank document and write one sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What problem am I trying to solve?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For our example, the &lt;em&gt;wrong&lt;/em&gt; answer would be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“People need a finance app”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;strong&gt;better&lt;/strong&gt; answer is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“People don’t know where their money goes, and most tracking apps feel too complex to use daily.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This sentence becomes the foundation of everything else.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: I Remove All Technical Language on Purpose
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzy6btmocjloxhu0yb39.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%2Fyzy6btmocjloxhu0yb39.png" alt="Removing Technical Complexity" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
At this stage, technical words are banned.&lt;/p&gt;

&lt;p&gt;No:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Database&lt;/li&gt;
&lt;li&gt;API&lt;/li&gt;
&lt;li&gt;Backend&lt;/li&gt;
&lt;li&gt;UI&lt;/li&gt;
&lt;li&gt;Stack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Only &lt;strong&gt;human language&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If I can’t explain the project without tech words, it means I don’t understand it well enough.&lt;/p&gt;

&lt;p&gt;This step forces clarity—and clarity is power.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: I Choose a Single, Specific User
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw85vwdg0pu1anyonh4t3.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%2Fw85vwdg0pu1anyonh4t3.png" alt="Choosing One Target User" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is where many projects quietly fail.&lt;/p&gt;

&lt;p&gt;I don’t build for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Everyone”&lt;/li&gt;
&lt;li&gt;“All users”&lt;/li&gt;
&lt;li&gt;“The market”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I build for &lt;strong&gt;one type of person&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For our expense app:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“A busy person who wants to quickly log expenses without thinking.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This single decision eliminates dozens of future arguments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do we need advanced charts? → No&lt;/li&gt;
&lt;li&gt;Do we need onboarding tutorials? → Minimal&lt;/li&gt;
&lt;li&gt;Do we need customization? → Probably not&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When the user is clear, complexity drops.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: I Write the User’s Day as a Story
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1rti7mqx8rvqz7chft2e.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%2F1rti7mqx8rvqz7chft2e.png" alt="Writing the User Story" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I imagine the project in real life.&lt;/p&gt;

&lt;p&gt;I write something like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“It’s the end of the day.&lt;br&gt;
The user bought lunch and paid for transport.&lt;br&gt;
They open the app.&lt;br&gt;
They immediately see an ‘Add Expense’ option.&lt;br&gt;
They enter amount and category.&lt;br&gt;
They see today’s total spending.&lt;br&gt;
They close the app feeling calm and aware.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This story does several things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It removes unnecessary features&lt;/li&gt;
&lt;li&gt;It highlights the main action&lt;/li&gt;
&lt;li&gt;It shows what &lt;em&gt;really&lt;/em&gt; matters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If something doesn’t appear in the story, it probably doesn’t belong in version one.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: I Define the Core Promise of the Project
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fahazyq4n1h9gs7bypidt.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%2Fahazyq4n1h9gs7bypidt.png" alt="Defining the Core Promise" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I write one sentence called the &lt;strong&gt;core promise&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“This app helps you quickly record expenses and see how much you spent today.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not five promises.&lt;br&gt;
Not a feature list.&lt;/p&gt;

&lt;p&gt;Just &lt;strong&gt;one promise&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every future decision must support this sentence.&lt;br&gt;
If it doesn’t, it waits.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: I Ruthlessly Cut Features (Before They Exist)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Falzwsffwykn8j503qsmw.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%2Falzwsffwykn8j503qsmw.png" alt="Ruthlessly Cut Features" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is uncomfortable—but critical.&lt;/p&gt;

&lt;p&gt;I create a section called:&lt;/p&gt;

&lt;h3&gt;
  
  
  “Things This Project Will NOT Do (Yet)”
&lt;/h3&gt;

&lt;p&gt;For our example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No monthly budgeting&lt;/li&gt;
&lt;li&gt;No charts or graphs&lt;/li&gt;
&lt;li&gt;No bank syncing&lt;/li&gt;
&lt;li&gt;No user accounts&lt;/li&gt;
&lt;li&gt;No cloud backup&lt;/li&gt;
&lt;li&gt;No AI insights&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Writing this down feels risky, but it creates &lt;strong&gt;focus and peace&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of feeling like I’m behind, I feel intentional.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 7: I Break the Project Into Mental Building Blocks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j5iwiu1mv4kxbixymb3.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%2F8j5iwiu1mv4kxbixymb3.png" alt="Breaking the Project into Parts" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now—and only now—I think about structure.&lt;/p&gt;

&lt;p&gt;Not code.&lt;br&gt;
Not files.&lt;/p&gt;

&lt;p&gt;Just &lt;strong&gt;parts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For the expense tracker:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Input expenses&lt;/li&gt;
&lt;li&gt;Save expenses&lt;/li&gt;
&lt;li&gt;Show today’s total&lt;/li&gt;
&lt;li&gt;Basic settings&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s the entire system.&lt;/p&gt;

&lt;p&gt;If I can’t describe the project in 4–6 blocks, it’s too big.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 8: I Sketch the Flow (Very Rough)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feq1t8vhzhujkdwxal8y0.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%2Feq1t8vhzhujkdwxal8y0.png" alt="Sketching the Flow" width="800" height="436"&gt;&lt;/a&gt;&lt;br&gt;
I might draw:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Boxes on paper&lt;/li&gt;
&lt;li&gt;Arrows between screens&lt;/li&gt;
&lt;li&gt;Or just bullet points&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Home → Add Expense → Back to Home&lt;/li&gt;
&lt;li&gt;Home → Today’s Summary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No design.&lt;br&gt;
No polish.&lt;/p&gt;

&lt;p&gt;Just logic.&lt;/p&gt;

&lt;p&gt;This step catches problems early—when fixing them is cheap.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 9: I Write a “Project Blueprint” Document
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzh8gs056tx8ndktwp9tp.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%2Fzh8gs056tx8ndktwp9tp.png" alt="Project Blueprint Document" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before coding, I always write this. Always.&lt;/p&gt;

&lt;p&gt;Here’s what it looks like for our example:&lt;/p&gt;




&lt;h3&gt;
  
  
  Project Name
&lt;/h3&gt;

&lt;p&gt;Simple Expense Tracker&lt;/p&gt;

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

&lt;p&gt;People struggle to track daily spending because existing apps feel complex.&lt;/p&gt;

&lt;h3&gt;
  
  
  Target User
&lt;/h3&gt;

&lt;p&gt;Busy individuals who want fast, low-effort expense tracking.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Promise
&lt;/h3&gt;

&lt;p&gt;Log expenses quickly and see daily totals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Actions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Add expense&lt;/li&gt;
&lt;li&gt;View today’s spending&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Out of Scope
&lt;/h3&gt;

&lt;p&gt;Budgets, charts, syncing, accounts, analytics&lt;/p&gt;

&lt;h3&gt;
  
  
  Success Looks Like
&lt;/h3&gt;

&lt;p&gt;A user can add an expense in under 10 seconds without confusion.&lt;/p&gt;




&lt;p&gt;This document is my &lt;strong&gt;anchor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Future me will thank present me for this.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 10: Only Now Do I Touch Technology
&lt;/h2&gt;

&lt;p&gt;Only after &lt;em&gt;everything above&lt;/em&gt; do I ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this web or mobile?&lt;/li&gt;
&lt;li&gt;How simple can the tech be?&lt;/li&gt;
&lt;li&gt;What’s the least complex solution?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overengineering feels silly&lt;/li&gt;
&lt;li&gt;Decisions are obvious&lt;/li&gt;
&lt;li&gt;Trade-offs are clear&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Technology becomes a tool—not the driver.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Process Works So Well
&lt;/h2&gt;

&lt;p&gt;It looks slow.&lt;br&gt;
It feels boring at first.&lt;/p&gt;

&lt;p&gt;But it saves enormous time later by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reducing rewrites&lt;/li&gt;
&lt;li&gt;Preventing scope creep&lt;/li&gt;
&lt;li&gt;Making decisions easier&lt;/li&gt;
&lt;li&gt;Increasing the chance of finishing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You trade early excitement for long-term momentum.&lt;/p&gt;




&lt;h2&gt;
  
  
  This Isn’t Just for Developers
&lt;/h2&gt;

&lt;p&gt;This approach works for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SaaS ideas&lt;/li&gt;
&lt;li&gt;Freelance projects&lt;/li&gt;
&lt;li&gt;Content platforms&lt;/li&gt;
&lt;li&gt;Newsletters&lt;/li&gt;
&lt;li&gt;Startups&lt;/li&gt;
&lt;li&gt;Personal side projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pattern is universal:&lt;br&gt;
&lt;strong&gt;Clarity → Structure → Execution&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8qfq4tx5lcq7bkgd0d3g.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%2F8qfq4tx5lcq7bkgd0d3g.png" alt="Final Thought" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Writing code feels productive.&lt;/p&gt;

&lt;p&gt;But &lt;strong&gt;knowing exactly what you’re building&lt;/strong&gt; is what actually gets projects finished.&lt;/p&gt;

&lt;p&gt;Now, whenever I feel stuck, I ask myself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Did I skip the thinking part?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most of the time, the answer is yes.&lt;/p&gt;

&lt;p&gt;So I go back—before the code.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>planning</category>
      <category>beginners</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>New Year, New You Portfolio Challenge Presented by Google AI</title>
      <dc:creator>Dulaj Thiwanka</dc:creator>
      <pubDate>Thu, 08 Jan 2026 04:19:12 +0000</pubDate>
      <link>https://dev.to/dthiwanka/new-year-new-you-portfolio-challenge-presented-by-google-ai-1448</link>
      <guid>https://dev.to/dthiwanka/new-year-new-you-portfolio-challenge-presented-by-google-ai-1448</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%2Fjjfvmc5v0d6fq3jsw6de.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%2Fjjfvmc5v0d6fq3jsw6de.png" alt="newyear"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/new-year-new-you-google-ai-2025-12-31"&gt;New Year, New You Portfolio Challenge Presented by Google AI&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About Me:
&lt;/h2&gt;

&lt;p&gt;Hi! 👋 I’m Dulaj Thiwanka, a passionate and dedicated Full Stack Developer with a strong foundation in building user-centric and scalable web applications. I graduated in Information Technology and specialize in technologies like React, Node.js, cloud services, and modern development tools. I enjoy solving complex problems, creating meaningful software solutions, and continuously expanding my skills—especially in areas like AI, prompt engineering, and cloud technologies. &lt;/p&gt;

&lt;p&gt;Beyond coding, I’m an avid learner and explorer—whether it’s new tech, creative problem-solving, or connecting with others who share similar goals. My portfolio showcases the projects I’ve built, from full-stack applications and IoT systems to RESTful APIs and dynamic user interfaces, with the aim of expressing my growth, versatility, and commitment to impactful tech. Through this portfolio, I hope to communicate not just what I can do, but what I’m eager to create next—whether that’s collaborating on meaningful projects, contributing to open-source, or pushing the boundaries of what technology can achieve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Portfolio:
&lt;/h2&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-netlify"&gt;
  &lt;iframe src="https://dulajthiwanka.netlify.app/" title="Netlify embed"&gt;
  &lt;/iframe&gt;
&lt;/div&gt;




&lt;h2&gt;
  
  
  How I Built It:
&lt;/h2&gt;

&lt;p&gt;This project was built using React with ViteJS for a fast, modern development experience and optimized performance. Tailwind CSS was chosen to create a clean, responsive, and consistent UI while allowing rapid iteration and customization.&lt;/p&gt;

&lt;p&gt;From a design perspective, I focused on simplicity, usability, and scalability—keeping the interface minimal while ensuring smooth user interaction and clear visual hierarchy. Components were structured to be reusable and maintainable, following best practices in modern frontend development.&lt;/p&gt;

&lt;p&gt;For AI integration, I embedded the Google Gemini API to enhance functionality with intelligent, context-aware responses. This allowed the application to demonstrate real-world AI usage, combining frontend performance with powerful generative AI capabilities.&lt;/p&gt;

&lt;p&gt;Overall, my development process emphasized modular architecture, performance optimization, and seamless AI integration, resulting in a polished and future-ready application.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm Most Proud Of:
&lt;/h2&gt;

&lt;p&gt;I’m most proud of successfully integrating Google’s Gemini API into a modern React application and making AI feel both accessible and practical within a clean user experience. Turning a powerful generative AI tool into something intuitive for users was a key achievement.&lt;/p&gt;

&lt;p&gt;From a technical standpoint, I’m proud of the performance and structure of the application—using ViteJS for fast builds, React component reusability, and Tailwind CSS for a responsive, visually consistent design. The project maintains a good balance between functionality and simplicity.&lt;/p&gt;

&lt;p&gt;I’m also proud of the overall development workflow, from planning the UI and component architecture to embedding AI features in a scalable way. This project represents my growth as a developer and my ability to combine modern frontend technologies with real-world AI integration to build meaningful, future-ready applications.&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%2Fzgsg80ye34kwtrt861b0.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%2Fzgsg80ye34kwtrt861b0.png" alt="My Portfolio"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>googleaichallenge</category>
      <category>portfolio</category>
      <category>gemini</category>
    </item>
    <item>
      <title>JWT vs OAuth: Why Everyone Argues, and Almost Everyone Is Slightly Wrong</title>
      <dc:creator>Dulaj Thiwanka</dc:creator>
      <pubDate>Thu, 08 Jan 2026 04:06:38 +0000</pubDate>
      <link>https://dev.to/dthiwanka/jwt-vs-oauth-why-everyone-argues-and-almost-everyone-is-slightly-wrong-5dgo</link>
      <guid>https://dev.to/dthiwanka/jwt-vs-oauth-why-everyone-argues-and-almost-everyone-is-slightly-wrong-5dgo</guid>
      <description>&lt;p&gt;JWT vs OAuth: Why Everyone Argues, and Almost Everyone Is Slightly Wrong&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%2F0zri3zgbqab6enege8h5.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%2F0zri3zgbqab6enege8h5.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At some point, usually after your first “secure” API ships to production, a quiet dread appears.&lt;/p&gt;

&lt;p&gt;You open your auth middleware.&lt;br&gt;
You stare at a token.&lt;br&gt;
You wonder if you &lt;em&gt;actually&lt;/em&gt; understand why this works.&lt;/p&gt;

&lt;p&gt;Then the question arrives:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Are we using JWT… or OAuth?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The problem is not the question.&lt;br&gt;
The problem is that the internet answers it like a shouting match instead of a conversation.&lt;/p&gt;

&lt;p&gt;So let’s have the conversation.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why This Topic Refuses to Stay Simple
&lt;/h2&gt;

&lt;p&gt;JWT and OAuth live in the same ecosystem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;both deal with tokens&lt;/li&gt;
&lt;li&gt;both show up in authentication flows&lt;/li&gt;
&lt;li&gt;both are involved in “secure APIs”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That overlap tricks people into thinking they solve the same problem.&lt;/p&gt;

&lt;p&gt;They don’t.&lt;/p&gt;

&lt;p&gt;They solve &lt;strong&gt;different problems at different layers&lt;/strong&gt;, and the confusion only exists because we keep collapsing layers to move faster.&lt;/p&gt;

&lt;p&gt;Speed is fun. Security remembers everything.&lt;/p&gt;


&lt;h2&gt;
  
  
  JWT: A Token That Refuses to Be Forgetful
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;JSON Web Token (JWT)&lt;/strong&gt; is a &lt;strong&gt;self-contained, verifiable data package&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Here are some claims.&lt;br&gt;
Here’s proof they haven’t been altered.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nothing more. Nothing less.&lt;/p&gt;

&lt;p&gt;A JWT has three parts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;header.payload.signature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;header&lt;/strong&gt; says how the token was signed&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;payload&lt;/strong&gt; contains claims (user ID, roles, expiration, etc.)&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;signature&lt;/strong&gt; proves integrity&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%2Fbfad213ffm0s6dgtotjh.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%2Fbfad213ffm0s6dgtotjh.png" alt="Image" width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpam9r4cpefkcv3i2rs53.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%2Fpam9r4cpefkcv3i2rs53.png" alt="Image" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fvantico.com.br%2Fwp-content%2Fuploads%2FDesign-sem-nome-87.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%2Fvantico.com.br%2Fwp-content%2Fuploads%2FDesign-sem-nome-87.png" alt="Image" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Seduction of Statelessness
&lt;/h3&gt;

&lt;p&gt;JWT’s biggest selling point is &lt;strong&gt;statelessness&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The server doesn’t remember sessions.&lt;br&gt;
It just verifies math.&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no session store&lt;/li&gt;
&lt;li&gt;no sticky sessions&lt;/li&gt;
&lt;li&gt;easy horizontal scaling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why JWT exploded alongside microservices and cloud-native systems.&lt;/p&gt;

&lt;p&gt;But stateless does &lt;strong&gt;not&lt;/strong&gt; mean consequence-free.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Trade-Off JWT Makes (And Never Warns You About)
&lt;/h2&gt;

&lt;p&gt;JWT trades &lt;strong&gt;control&lt;/strong&gt; for &lt;strong&gt;performance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once issued:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the server can’t easily revoke it&lt;/li&gt;
&lt;li&gt;the token lives until it expires&lt;/li&gt;
&lt;li&gt;whoever has it &lt;em&gt;is&lt;/em&gt; the user&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is fine when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tokens are short-lived&lt;/li&gt;
&lt;li&gt;scopes are narrow&lt;/li&gt;
&lt;li&gt;refresh strategies are sane&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s dangerous when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tokens last days or weeks&lt;/li&gt;
&lt;li&gt;secrets leak into payloads&lt;/li&gt;
&lt;li&gt;JWT is treated like a magical session replacement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JWT is a sharp knife.&lt;br&gt;
It cuts beautifully.&lt;br&gt;
It does not ask permission.&lt;/p&gt;




&lt;h2&gt;
  
  
  OAuth: The Art of Delegated Trust
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg843tk9y9fdzbk17vgep.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%2Fg843tk9y9fdzbk17vgep.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OAuth is not about identity.&lt;/p&gt;

&lt;p&gt;OAuth is about &lt;strong&gt;permission&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It exists to answer one specific question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Is this application allowed to access that resource on behalf of this user?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s it.&lt;br&gt;
No identity. No emotions. Just boundaries.&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%2Fwafxxxtwf5op4l9fpflo.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%2Fwafxxxtwf5op4l9fpflo.png" alt="Image" width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn66xg6p2fpppyfwxkkdb.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%2Fn66xg6p2fpppyfwxkkdb.png" alt="Image" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7sl0p9ttf0yzk08fvm0g.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%2F7sl0p9ttf0yzk08fvm0g.png" alt="Image" width="431" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OAuth introduces formal roles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resource Owner&lt;/strong&gt; – the user&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client&lt;/strong&gt; – the application&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authorization Server&lt;/strong&gt; – issues tokens&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Server&lt;/strong&gt; – protects data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This structure feels heavy because trust &lt;em&gt;is&lt;/em&gt; heavy.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why OAuth Feels Complicated (Because It Is)
&lt;/h2&gt;

&lt;p&gt;OAuth wasn’t designed for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;small apps&lt;/li&gt;
&lt;li&gt;solo projects&lt;/li&gt;
&lt;li&gt;“just log the user in”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was designed for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ecosystems&lt;/li&gt;
&lt;li&gt;third-party access&lt;/li&gt;
&lt;li&gt;companies that do not trust each other (correctly)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OAuth assumes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multiple apps&lt;/li&gt;
&lt;li&gt;limited permissions&lt;/li&gt;
&lt;li&gt;tokens that can be revoked&lt;/li&gt;
&lt;li&gt;scopes that matter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s verbose because ambiguity is dangerous.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Moment Everyone Gets Fooled: “Login With Google”
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2jerfgbidpmnhwqixdsz.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%2F2jerfgbidpmnhwqixdsz.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s the twist that breaks brains:&lt;/p&gt;

&lt;p&gt;When you “log in” with Google, you’re &lt;strong&gt;not using OAuth alone&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You’re using &lt;strong&gt;OpenID Connect (OIDC)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;OIDC is an &lt;strong&gt;identity layer on top of OAuth 2.0&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;OAuth says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“This app may access this resource.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;OIDC adds:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“And here is who the user actually is.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Without OIDC, OAuth does not authenticate humans.&lt;br&gt;
It authorizes software.&lt;/p&gt;




&lt;h2&gt;
  
  
  How JWT, OAuth, and OIDC Actually Work Together
&lt;/h2&gt;

&lt;p&gt;This is the real-world flow most systems use, even if they don’t realize it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User authenticates via OIDC&lt;/li&gt;
&lt;li&gt;Authorization server validates identity&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;access token&lt;/strong&gt; is issued&lt;/li&gt;
&lt;li&gt;That access token is often a &lt;strong&gt;JWT&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;APIs verify the JWT signature locally&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;JWT becomes the &lt;strong&gt;container&lt;/strong&gt;.&lt;br&gt;
OAuth defines &lt;strong&gt;who may receive it&lt;/strong&gt;.&lt;br&gt;
OIDC defines &lt;strong&gt;who the user is&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is not redundancy.&lt;br&gt;
This is layering.&lt;/p&gt;




&lt;h2&gt;
  
  
  Access Tokens vs Refresh Tokens (Where Many Breaches Begin)
&lt;/h2&gt;

&lt;p&gt;Not all tokens are equal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Access tokens&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;short-lived&lt;/li&gt;
&lt;li&gt;sent with every request&lt;/li&gt;
&lt;li&gt;frequently JWTs&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Refresh tokens&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;long-lived&lt;/li&gt;
&lt;li&gt;never sent to APIs&lt;/li&gt;
&lt;li&gt;used only to obtain new access tokens&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;If your refresh token leaks, you have a real problem.&lt;/p&gt;

&lt;p&gt;If your access token leaks, expiry limits the blast radius.&lt;/p&gt;

&lt;p&gt;Security is about &lt;strong&gt;containing damage&lt;/strong&gt;, not preventing mistakes.&lt;/p&gt;




&lt;h2&gt;
  
  
  When JWT Alone Is Enough
&lt;/h2&gt;

&lt;p&gt;JWT-only authentication is reasonable when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you control the entire system&lt;/li&gt;
&lt;li&gt;users don’t need third-party login&lt;/li&gt;
&lt;li&gt;permissions are simple&lt;/li&gt;
&lt;li&gt;tokens expire quickly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is common in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;internal tools&lt;/li&gt;
&lt;li&gt;early-stage products&lt;/li&gt;
&lt;li&gt;mobile apps with a single backend&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JWT shines in closed worlds.&lt;/p&gt;




&lt;h2&gt;
  
  
  When OAuth/OIDC Is Worth the Pain
&lt;/h2&gt;

&lt;p&gt;OAuth and OIDC earn their keep when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;users expect social login&lt;/li&gt;
&lt;li&gt;multiple clients exist (web, mobile, partners)&lt;/li&gt;
&lt;li&gt;APIs are exposed externally&lt;/li&gt;
&lt;li&gt;access must be scoped and revocable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;OAuth is not overengineering.&lt;br&gt;
It’s &lt;em&gt;honest engineering&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Persistent Myths That Refuse to Die
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;“JWT is more secure than OAuth”&lt;/strong&gt;&lt;br&gt;
They solve different problems. Stop comparing them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“OAuth replaces JWT”&lt;/strong&gt;&lt;br&gt;
OAuth frequently uses JWT as its token format.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“JWT payloads are private”&lt;/strong&gt;&lt;br&gt;
They are readable. Assume visibility.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Stateless means simpler”&lt;/strong&gt;&lt;br&gt;
Stateless means fewer knobs when things go wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Mental Model That Actually Works
&lt;/h2&gt;

&lt;p&gt;If nothing else sticks, let this one stick:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JWT&lt;/strong&gt; → how claims are packaged&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OAuth&lt;/strong&gt; → who may access what&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OIDC&lt;/strong&gt; → who the user is&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you separate those layers, the noise fades.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought: Security Is Memory
&lt;/h2&gt;

&lt;p&gt;Security systems are not about clever code.&lt;br&gt;
They are about remembering past decisions under pressure.&lt;/p&gt;

&lt;p&gt;JWT remembers claims.&lt;br&gt;
OAuth remembers permissions.&lt;br&gt;
OIDC remembers identity.&lt;/p&gt;

&lt;p&gt;Confusion happens when we forget &lt;em&gt;why&lt;/em&gt; each one exists.&lt;/p&gt;

&lt;p&gt;Clarity is not optional here.&lt;br&gt;
It’s the difference between a clean audit and a long incident report.&lt;/p&gt;

&lt;p&gt;And incident reports are never written at pleasant hours.&lt;/p&gt;

&lt;p&gt;Read on Medium : &lt;a href="https://medium.com/@dulthiwanka2015/jwt-vs-oauth-why-everyone-argues-and-almost-everyone-is-slightly-wrong-0f77469491ec?postPublishedType=initial" rel="noopener noreferrer"&gt;Medium Article&lt;/a&gt;&lt;/p&gt;

</description>
      <category>jwt</category>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Vibe Coding: Shipping Code While the Brain Is Still Happy</title>
      <dc:creator>Dulaj Thiwanka</dc:creator>
      <pubDate>Wed, 10 Dec 2025 09:40:20 +0000</pubDate>
      <link>https://dev.to/dthiwanka/vibe-coding-shipping-code-while-the-brain-is-still-happy-1e0j</link>
      <guid>https://dev.to/dthiwanka/vibe-coding-shipping-code-while-the-brain-is-still-happy-1e0j</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%2Ftsc10ubi728iien7f6db.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%2Ftsc10ubi728iien7f6db.png" alt="firstImg" width="800" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You know that moment when everything clicks?&lt;/p&gt;

&lt;p&gt;The editor feels fast.&lt;br&gt;
The idea is clear.&lt;br&gt;
You’re not googling every 30 seconds.&lt;br&gt;
The code is flowing and you &lt;em&gt;don’t want to stop&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That’s the vibe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vibe Coding&lt;/strong&gt; is leaning into that state instead of fighting it with over-engineering, premature rules, and 12 tabs of documentation you didn’t need yet.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is Vibe Coding (In Plain Dev Terms)
&lt;/h2&gt;

&lt;p&gt;Vibe Coding isn’t a framework.&lt;br&gt;
It’s not “cowboy coding”.&lt;br&gt;
It’s not an excuse to ship garbage.&lt;/p&gt;

&lt;p&gt;It’s a &lt;strong&gt;way of working&lt;/strong&gt; where you optimize for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flow&lt;/li&gt;
&lt;li&gt;Momentum&lt;/li&gt;
&lt;li&gt;Mental clarity&lt;/li&gt;
&lt;li&gt;Enjoyment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You write code that makes sense &lt;em&gt;right now&lt;/em&gt;, and you trust yourself to make it better later.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Things That Make Up Vibe Coding
&lt;/h2&gt;

&lt;p&gt;Think of Vibe Coding as a small toolkit, not a philosophy lecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Momentum Over Perfection
&lt;/h3&gt;

&lt;p&gt;If you stop every 5 minutes to “do it properly”, you kill the idea before it’s alive.&lt;/p&gt;

&lt;p&gt;Get it working first.&lt;br&gt;
Make it pretty later.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Low Cognitive Load
&lt;/h3&gt;

&lt;p&gt;Your brain has limited RAM.&lt;/p&gt;

&lt;p&gt;Vibe Coding means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fewer abstractions early&lt;/li&gt;
&lt;li&gt;Fewer files at the start&lt;/li&gt;
&lt;li&gt;Obvious names over clever ones&lt;/li&gt;
&lt;li&gt;Straight lines instead of fancy patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple code = more brain space for the actual problem.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Feedback Loops That Are Instant
&lt;/h3&gt;

&lt;p&gt;Fast feedback keeps the vibe alive.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hot reload&lt;/li&gt;
&lt;li&gt;Live preview&lt;/li&gt;
&lt;li&gt;Console logs (yes, really)&lt;/li&gt;
&lt;li&gt;Visual output over theory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If feedback is slow, motivation dies quietly.&lt;/p&gt;




&lt;h3&gt;
  
  
  4. Code That Feels Readable
&lt;/h3&gt;

&lt;p&gt;Not “enterprise clean”.&lt;br&gt;
Not “leetcode clever”.&lt;/p&gt;

&lt;p&gt;Just:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Yeah… I get what this does.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Readable code keeps you in flow longer.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. Emotional Awareness (Underrated Skill)
&lt;/h3&gt;

&lt;p&gt;Vibe Coding includes noticing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you’re tired&lt;/li&gt;
&lt;li&gt;When you’re forcing it&lt;/li&gt;
&lt;li&gt;When flow is gone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pushing through bad mental states usually creates bad code.&lt;/p&gt;

&lt;p&gt;Stopping is a skill.&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%2F47mb7821smpx8qf8itxr.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%2F47mb7821smpx8qf8itxr.png" alt="secondImg" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Actually Practice Vibe Coding (Step-by-Step)
&lt;/h2&gt;

&lt;p&gt;This is the part most articles skip.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Start Before You Feel Ready
&lt;/h3&gt;

&lt;p&gt;If you wait for the perfect plan, you’ll never start.&lt;/p&gt;

&lt;p&gt;Open the editor.&lt;br&gt;
Create the file.&lt;br&gt;
Write the ugly first version.&lt;/p&gt;

&lt;p&gt;Motion creates clarity.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 2: Build the “Stupid Version” First
&lt;/h3&gt;

&lt;p&gt;Ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“What’s the dumbest possible version that works?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hardcode things.&lt;br&gt;
Duplicate code.&lt;br&gt;
Ignore edge cases.&lt;/p&gt;

&lt;p&gt;You’re sketching, not painting.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 3: Stay in One Mental Mode
&lt;/h3&gt;

&lt;p&gt;Don’t mix:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Designing&lt;/li&gt;
&lt;li&gt;Optimizing&lt;/li&gt;
&lt;li&gt;Refactoring&lt;/li&gt;
&lt;li&gt;Naming perfectly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pick one mode.&lt;br&gt;
Vibe Coding mode = &lt;strong&gt;build mode&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 4: Let Patterns Appear Naturally
&lt;/h3&gt;

&lt;p&gt;Once you see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repeated logic&lt;/li&gt;
&lt;li&gt;Similar components&lt;/li&gt;
&lt;li&gt;Copy-paste growing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s your signal to refactor.&lt;/p&gt;

&lt;p&gt;Refactoring before patterns exist is just guessing.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 5: Refactor in Short, Focused Bursts
&lt;/h3&gt;

&lt;p&gt;Refactor &lt;em&gt;after&lt;/em&gt; momentum, not during it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rename things&lt;/li&gt;
&lt;li&gt;Extract functions&lt;/li&gt;
&lt;li&gt;Clean files&lt;/li&gt;
&lt;li&gt;Add types/tests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then stop.&lt;br&gt;
Don’t spiral.&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 6: Lock It Down Before Shipping
&lt;/h3&gt;

&lt;p&gt;Vibe Coding ends before production.&lt;/p&gt;

&lt;p&gt;Before shipping:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Handle edge cases&lt;/li&gt;
&lt;li&gt;Add validation&lt;/li&gt;
&lt;li&gt;Clean obvious messes&lt;/li&gt;
&lt;li&gt;Remove debug junk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vibe ≠ reckless.&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%2F9seaopc2ec657riivxc9.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%2F9seaopc2ec657riivxc9.png" alt="ThridImg" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Things That Help the Vibe (Surprisingly Practical)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Environment Things
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Editor theme you enjoy&lt;/li&gt;
&lt;li&gt;Font that doesn’t strain your eyes&lt;/li&gt;
&lt;li&gt;Minimal UI clutter&lt;/li&gt;
&lt;li&gt;Comfortable keyboard/layout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your environment affects your thinking more than you think.&lt;/p&gt;




&lt;h3&gt;
  
  
  Workflow Things
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;One task at a time&lt;/li&gt;
&lt;li&gt;One screen if possible&lt;/li&gt;
&lt;li&gt;Notifications off&lt;/li&gt;
&lt;li&gt;Clear goal for the session&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vibe dies when attention fragments.&lt;/p&gt;




&lt;h3&gt;
  
  
  Mental Things
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Accept messy first drafts&lt;/li&gt;
&lt;li&gt;Don’t judge code too early&lt;/li&gt;
&lt;li&gt;Don’t compare mid-work&lt;/li&gt;
&lt;li&gt;Treat coding like writing, not math&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Drafts are allowed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Where Vibe Coding Works Best
&lt;/h2&gt;

&lt;p&gt;Vibe Coding shines in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Side projects&lt;/li&gt;
&lt;li&gt;MVPs&lt;/li&gt;
&lt;li&gt;Hackathons&lt;/li&gt;
&lt;li&gt;UI-heavy apps&lt;/li&gt;
&lt;li&gt;Learning new frameworks&lt;/li&gt;
&lt;li&gt;Creative experiments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It struggles in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Safety-critical systems&lt;/li&gt;
&lt;li&gt;Compliance-heavy apps&lt;/li&gt;
&lt;li&gt;Massive legacy codebases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Context matters. Always.&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%2Fdojgchtbz29qzs5vphw2.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%2Fdojgchtbz29qzs5vphw2.png" alt="VibeCodingWithAI" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Vibe Coding With AI (Use Carefully)
&lt;/h2&gt;

&lt;p&gt;AI is amazing for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Boilerplate&lt;/li&gt;
&lt;li&gt;Scaffolding&lt;/li&gt;
&lt;li&gt;Explaining errors&lt;/li&gt;
&lt;li&gt;Unblocking flow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI is bad at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Architecture decisions&lt;/li&gt;
&lt;li&gt;Product judgment&lt;/li&gt;
&lt;li&gt;Knowing your context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use AI to &lt;em&gt;support&lt;/em&gt; the vibe, not replace thinking.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Mistakes People Make
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Never refactoring&lt;/li&gt;
&lt;li&gt;Using “vibe” as an excuse for chaos&lt;/li&gt;
&lt;li&gt;Shipping prototypes to production&lt;/li&gt;
&lt;li&gt;Ignoring tests forever&lt;/li&gt;
&lt;li&gt;Coding while exhausted and angry&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vibe Coding still requires responsibility.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Vibe Coding is about respecting how humans actually think.&lt;/p&gt;

&lt;p&gt;Flow beats force.&lt;br&gt;
Momentum beats over-planning.&lt;br&gt;
Clarity beats cleverness.&lt;/p&gt;

&lt;p&gt;Write the code that lets you keep going.&lt;/p&gt;

&lt;p&gt;Clean it later.&lt;br&gt;
Ship it when it’s ready.&lt;br&gt;
And enjoy the process — that’s usually where the best ideas show up.&lt;/p&gt;

&lt;p&gt;Follow Me : &lt;a href="https://medium.com/@dulthiwanka2015" rel="noopener noreferrer"&gt;https://medium.com/@dulthiwanka2015&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>vibecoding</category>
      <category>ai</category>
      <category>coding</category>
    </item>
    <item>
      <title>Top Postman Alternatives for API Testing in 2025</title>
      <dc:creator>Dulaj Thiwanka</dc:creator>
      <pubDate>Fri, 21 Nov 2025 10:52:22 +0000</pubDate>
      <link>https://dev.to/dthiwanka/top-postman-alternatives-for-api-testing-in-2025-171n</link>
      <guid>https://dev.to/dthiwanka/top-postman-alternatives-for-api-testing-in-2025-171n</guid>
      <description>&lt;p&gt;Postman is popular, but many developers are exploring alternatives for &lt;strong&gt;lightweight testing, automation, or enterprise workflows&lt;/strong&gt;. Here’s a curated list of top tools you can use in 2025.&lt;/p&gt;




&lt;h2&gt;
  
  
  🖥️ 1. Insomnia
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mqqohlehtu5flo451e0.jpg" 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%2F0mqqohlehtu5flo451e0.jpg" alt="Insomnia" width="440" height="280"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Type:&lt;/strong&gt; GUI | &lt;strong&gt;Platforms:&lt;/strong&gt; Mac, Windows, Linux | &lt;strong&gt;Open Source&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Supports &lt;strong&gt;REST, GraphQL, gRPC&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Clean, intuitive interface&lt;/li&gt;
&lt;li&gt;Design-first workflows: variables, environments, Git sync&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ideal for developers who want a visually clean tool with advanced workflow support.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🌟 2. Hoppscotch (formerly Postwoman)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fav5y7jb7rysgl37b7msu.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%2Fav5y7jb7rysgl37b7msu.png" alt="Hoppscotch " width="800" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type:&lt;/strong&gt; Browser-based | &lt;strong&gt;Platforms:&lt;/strong&gt; Web | &lt;strong&gt;Open Source&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Minimal setup, no installation needed&lt;/li&gt;
&lt;li&gt;Supports &lt;strong&gt;REST, GraphQL, WebSocket&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Lightweight and fast&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Perfect for developers wanting a &lt;strong&gt;no-installation, fast API client&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ⚡ 3. Thunder Client
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj47m0ohmqei5m7anjov5.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%2Fj47m0ohmqei5m7anjov5.png" alt="Thunder_Client" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type:&lt;/strong&gt; VS Code Extension | &lt;strong&gt;Platforms:&lt;/strong&gt; VS Code | &lt;strong&gt;Open Source&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Test APIs without leaving VS Code&lt;/li&gt;
&lt;li&gt;Collections stored as &lt;strong&gt;JSON&lt;/strong&gt; for version control&lt;/li&gt;
&lt;li&gt;Lightweight and simple&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ideal for developers who prefer &lt;strong&gt;editor-integrated tools&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  💻 4. HTTPie
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj52wa522w3ghqwkrmvb2.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%2Fj52wa522w3ghqwkrmvb2.png" alt="HTTPie" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type:&lt;/strong&gt; CLI / GUI | &lt;strong&gt;Platforms:&lt;/strong&gt; Cross-platform | &lt;strong&gt;Open Source&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Command-line HTTP client with &lt;strong&gt;human-friendly syntax&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;GUI available for scripting or automation integration&lt;/li&gt;
&lt;li&gt;Ideal for &lt;strong&gt;automation and CI/CD pipelines&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Perfect for CLI enthusiasts and automation workflows.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧪 5. SoapUI / ReadyAPI
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F492xxkngj88ezphybtfo.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%2F492xxkngj88ezphybtfo.png" alt="ReadyAPI" width="600" height="315"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Type:&lt;/strong&gt; GUI | &lt;strong&gt;Platforms:&lt;/strong&gt; Cross-platform | &lt;strong&gt;Open Source / Commercial&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;SoapUI: free, supports &lt;strong&gt;REST and SOAP&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;ReadyAPI: enterprise-level with load testing, virtualization, advanced features&lt;/li&gt;
&lt;li&gt;Great for &lt;strong&gt;robust testing and enterprise needs&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Suited for teams needing &lt;strong&gt;full-featured API testing solutions&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🚀 6. Katalon Studio
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F88qe0s0fg8sysr5fpj9a.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%2F88qe0s0fg8sysr5fpj9a.png" alt="KatalonStudio" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type:&lt;/strong&gt; GUI | &lt;strong&gt;Platforms:&lt;/strong&gt; Mac, Windows, Linux | &lt;strong&gt;Free / Commercial&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Supports &lt;strong&gt;web, mobile, desktop, API testing&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Designed for &lt;strong&gt;automation, CI/CD, and data-driven tests&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;All-in-one solution for teams wanting &lt;strong&gt;cross-platform testing&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ☕ 7. REST-Assured
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fencrypted-tbn0.gstatic.com%2Fimages%3Fq%3Dtbn%3AANd9GcTx2BoZf-nQXK6CNdeFsXyl590aWMnnd_x3og%26s" 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%2Fencrypted-tbn0.gstatic.com%2Fimages%3Fq%3Dtbn%3AANd9GcTx2BoZf-nQXK6CNdeFsXyl590aWMnnd_x3og%26s" alt="REST-Assured" width="406" height="124"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Type:&lt;/strong&gt; Library (Java) | &lt;strong&gt;Platforms:&lt;/strong&gt; JVM | &lt;strong&gt;Open Source&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Java-based API testing library&lt;/li&gt;
&lt;li&gt;Easily integrates with &lt;strong&gt;CI pipelines or automation frameworks&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Best for &lt;strong&gt;Java developers embedding tests in code&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  📖 8. Karate DSL
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fencrypted-tbn0.gstatic.com%2Fimages%3Fq%3Dtbn%3AANd9GcSldvFtMvDjzFIceB_-E-irDu0AcHtPuxonXg%26s" 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%2Fencrypted-tbn0.gstatic.com%2Fimages%3Fq%3Dtbn%3AANd9GcSldvFtMvDjzFIceB_-E-irDu0AcHtPuxonXg%26s" alt="KarateDSL" width="300" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type:&lt;/strong&gt; Library (Java/Groovy) | &lt;strong&gt;Platforms:&lt;/strong&gt; JVM | &lt;strong&gt;Open Source&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;BDD-style syntax for &lt;strong&gt;readable and maintainable tests&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Supports &lt;strong&gt;REST, GraphQL, mocks, performance testing&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Great for &lt;strong&gt;BDD-focused testing workflows&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🏢 9. Parasoft SOAtest
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8lx4jdr7qysi2gpfg0fh.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%2F8lx4jdr7qysi2gpfg0fh.png" alt="Parasoft SOAtest" width="600" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type:&lt;/strong&gt; GUI | &lt;strong&gt;Platforms:&lt;/strong&gt; Cross-platform | &lt;strong&gt;Commercial&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Enterprise-grade tool for &lt;strong&gt;SOAP, REST, etc.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Functional testing, security testing, mocking, performance testing&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Perfect for &lt;strong&gt;large organizations needing full-featured enterprise solutions&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🎯 10. Apidog
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0kzbw7hde74bft6tufl5.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%2F0kzbw7hde74bft6tufl5.png" alt="Apidog" width="800" height="295"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type:&lt;/strong&gt; GUI | &lt;strong&gt;Platforms:&lt;/strong&gt; Web / Cross-platform | &lt;strong&gt;Commercial / Affordable&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Combines &lt;strong&gt;API design and testing&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Supports &lt;strong&gt;REST, GraphQL, WebSocket, gRPC&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Cheaper than other enterprise tools&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Ideal for &lt;strong&gt;startups or small teams&lt;/strong&gt; needing both &lt;strong&gt;design + testing in one platform&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Main Article : &lt;a href="https://medium.com/@dulthiwanka2015/top-postman-alternatives-for-api-testing-in-2025-a860b3eca7d0?postPublishedType=initial" rel="noopener noreferrer"&gt;https://medium.com/@dulthiwanka2015/top-postman-alternatives-for-api-testing-in-2025-a860b3eca7d0?postPublishedType=initial&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>testing</category>
      <category>tooling</category>
      <category>resources</category>
    </item>
    <item>
      <title>Using Console Colors with Node.js: A Complete Guide for Cleaner, Smarter Terminal Output</title>
      <dc:creator>Dulaj Thiwanka</dc:creator>
      <pubDate>Fri, 14 Nov 2025 10:18:14 +0000</pubDate>
      <link>https://dev.to/dthiwanka/using-console-colors-with-nodejs-a-complete-guide-for-cleaner-smarter-terminal-output-a7k</link>
      <guid>https://dev.to/dthiwanka/using-console-colors-with-nodejs-a-complete-guide-for-cleaner-smarter-terminal-output-a7k</guid>
      <description>&lt;p&gt;Terminal output is the heartbeat of backend developers. Whether you're debugging a stubborn API issue, running background jobs, or building a CLI tool, the console is your most constant companion. Adding color to that output transforms a flood of text into an organized dashboard for your brain.&lt;/p&gt;

&lt;p&gt;Node.js makes this surprisingly easy. This guide digs into how console colors really work, common libraries, advanced tricks, and practical patterns for using them effectively.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Console Colors Work Under the Hood
&lt;/h2&gt;

&lt;p&gt;Terminals support something called &lt;strong&gt;ANSI escape codes&lt;/strong&gt;, tiny embedded instructions inside strings that change how text appears. These color codes have been around since the early days of UNIX.&lt;/p&gt;

&lt;p&gt;A simple example looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;\x1b[31mHello\x1b[0m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;\x1b&lt;/code&gt; means ESC (escape).&lt;br&gt;
&lt;code&gt;[31m&lt;/code&gt; means “switch to red”.&lt;br&gt;
&lt;code&gt;[0m&lt;/code&gt; means “reset styles”.&lt;/p&gt;

&lt;p&gt;Node.js outputs this directly to your terminal when you call:&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;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="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;x1b[31mThis is red&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;x1b[0m&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;This gives you bare-metal control, which is useful once you understand the pattern.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core ANSI Color Codes (Reference)
&lt;/h2&gt;

&lt;p&gt;Foreground colors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Black: &lt;code&gt;\x1b[30m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Red: &lt;code&gt;\x1b[31m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Green: &lt;code&gt;\x1b[32m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Yellow: &lt;code&gt;\x1b[33m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Blue: &lt;code&gt;\x1b[34m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Magenta: &lt;code&gt;\x1b[35m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Cyan: &lt;code&gt;\x1b[36m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;White: &lt;code&gt;\x1b[37m&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Background colors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Red background: &lt;code&gt;\x1b[41m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Green background: &lt;code&gt;\x1b[42m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Yellow background: &lt;code&gt;\x1b[43m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Blue background: &lt;code&gt;\x1b[44m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Magenta background: &lt;code&gt;\x1b[45m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Cyan background: &lt;code&gt;\x1b[46m&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Style modifiers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bold: &lt;code&gt;\x1b[1m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Dim: &lt;code&gt;\x1b[2m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Italic: &lt;code&gt;\x1b[3m&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Underline: &lt;code&gt;\x1b[4m&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reset:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reset all: &lt;code&gt;\x1b[0m&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These codes stack, which lets you do things like:&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;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="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;x1b[1m&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;x1b[33mBold Yellow&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;x1b[0m&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;It’s low-level, but powerful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Using Chalk for Cleaner Syntax and Modern Features
&lt;/h2&gt;

&lt;p&gt;Working with raw escape codes is like writing HTML inline styles everywhere. Chalk fixes that with a clean API.&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%2Fe96vb422w4zvr59scpoz.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%2Fe96vb422w4zvr59scpoz.png" alt="Chalk Logo" width="529" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;chalk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;chalk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chalk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;red&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;green&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Warning&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Info message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Chalk Highlights
&lt;/h3&gt;

&lt;p&gt;Chalk gives you three key advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cleaner syntax&lt;/strong&gt;&lt;br&gt;
No escape code juggling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automatic color support detection&lt;/strong&gt;&lt;br&gt;
Some terminals don’t support color. Chalk gracefully downgrades.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nested &amp;amp; chained styling&lt;/strong&gt;&lt;br&gt;
Chalk handles resets for you.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bgRed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;white&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; Critical System Failure &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Extended Color Support
&lt;/h3&gt;

&lt;p&gt;Chalk supports 256-color and TrueColor (16 million colors):&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#ff8800&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Orange heading&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rgb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Custom tone&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;This is useful when designing CLI tools that need branding or visual structure.&lt;/p&gt;




&lt;h2&gt;
  
  
  Using &lt;code&gt;colors&lt;/code&gt; for Inline Style Shortcuts
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F60maw2zlmguyo1vwrdbj.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%2F60maw2zlmguyo1vwrdbj.png" alt="Colors Desc" width="566" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;colors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;colors&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Updated successfully&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;green&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;Something went wrong&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;red&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bold&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;Check configuration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;underline&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Caveat: Prototype Modification
&lt;/h3&gt;

&lt;p&gt;This library modifies the &lt;code&gt;String.prototype&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Great for small scripts.&lt;br&gt;
Not ideal for large or shared codebases.&lt;/p&gt;


&lt;h2&gt;
  
  
  Using &lt;code&gt;kleur&lt;/code&gt; for a Lightweight Alternative
&lt;/h2&gt;

&lt;p&gt;If you want Chalk-like features with a smaller footprint:&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%2Fw87j0ia8qwuol57kc821.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%2Fw87j0ia8qwuol57kc821.png" alt="kleur Logo" width="800" height="294"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;kleur
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;kleur&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;kleur&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;kleur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;red&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="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;kleur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bold&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;green&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;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;kleur&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bgYellow&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;black&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Warning&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;kleur&lt;/code&gt; is fast and tiny, good for performance-sensitive CLI tools.&lt;/p&gt;




&lt;h2&gt;
  
  
  Formatting Output with &lt;code&gt;console&lt;/code&gt; Methods
&lt;/h2&gt;

&lt;p&gt;Node gives you some built-in variations:&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;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;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;red&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Fatal error&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;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Warning&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;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Info&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;green&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Done&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;Each has a semantic purpose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;console.error()&lt;/code&gt; prints to stderr&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;console.log()&lt;/code&gt; prints to stdout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters when scripting or logging to other processes.&lt;/p&gt;




&lt;h2&gt;
  
  
  Detecting If Colors Are Supported
&lt;/h2&gt;

&lt;p&gt;Some environments strip ANSI codes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker logs&lt;/li&gt;
&lt;li&gt;CI systems&lt;/li&gt;
&lt;li&gt;Windows terminal (older versions)&lt;/li&gt;
&lt;li&gt;File exports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chalk makes detection easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;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;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;supportsColor&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;Your terminal doesn't support color&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;Manual detection:&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;colorSupported&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isTTY&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good CLI tools gracefully degrade.&lt;/p&gt;




&lt;h2&gt;
  
  
  Creating a Reusable Logger with Colors
&lt;/h2&gt;

&lt;p&gt;A small logger can unify styles for an entire project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;chalk&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chalk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[INFO]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;green&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[SUCCESS]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[WARN]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;chalk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;red&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[ERROR]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Server started&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Database 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;log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;High memory usage&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;log&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Failed to load config&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;This gives your project consistent, structured output.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tips for Designing Color Logic
&lt;/h2&gt;

&lt;p&gt;A few guidelines from writing CLI tools:&lt;/p&gt;

&lt;p&gt;• Use &lt;strong&gt;color for meaning&lt;/strong&gt;, not decoration.&lt;br&gt;
• Reserve red for actual errors.&lt;br&gt;
• Yellow works best for non-critical warnings.&lt;br&gt;
• Magenta and cyan help differentiate categories.&lt;br&gt;
• Don’t overload a single line with too many styles.&lt;br&gt;
• Test output in multiple terminals.&lt;/p&gt;

&lt;p&gt;A good rule: if every line is colorful, none of them matter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Colored console output is more than an aesthetic trick. It’s a tight feedback loop for developers, a way of turning raw text into a readable system of symbols. Once you understand ANSI codes and the available Node.js libraries, you can design output that actually helps you think.&lt;/p&gt;

&lt;p&gt;This small skill pays off when you build tools, monitor logs, debug servers, or shape your own development workflow. Exploring this further even opens paths into advanced CLI UI frameworks like Ink, Commander.js integration, loading spinners, progress bars, and full interactive terminal interfaces.&lt;/p&gt;

&lt;p&gt;Color is just the beginning.&lt;/p&gt;

</description>
      <category>node</category>
      <category>programming</category>
      <category>backend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Understanding the MERN Stack for Beginners</title>
      <dc:creator>Dulaj Thiwanka</dc:creator>
      <pubDate>Tue, 11 Nov 2025 04:24:29 +0000</pubDate>
      <link>https://dev.to/dthiwanka/understanding-the-mern-stack-for-beginners-13jc</link>
      <guid>https://dev.to/dthiwanka/understanding-the-mern-stack-for-beginners-13jc</guid>
      <description>&lt;p&gt;The &lt;strong&gt;MERN Stack&lt;/strong&gt; is one of the most popular and practical ways to build modern web applications. If you're interested in becoming a &lt;strong&gt;full-stack developer&lt;/strong&gt;, learning MERN gives you the skills to create complete apps — everything from the visual interface to the database behind the scenes.&lt;/p&gt;

&lt;p&gt;And the best part? You only need to know &lt;strong&gt;JavaScript&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This guide expands your understanding step-by-step, keeping things friendly, practical, and beginner-focused.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the MERN Stack?
&lt;/h2&gt;

&lt;p&gt;MERN is made up of four core technologies:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Letter&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;M&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;MongoDB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stores your application's data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;E&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Express.js&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Handles backend logic and API routing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;R&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;React.js&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Builds the user interface (UI)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;N&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Node.js&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Runs JavaScript on the server&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These four pieces work &lt;strong&gt;together&lt;/strong&gt; to create a complete web app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Learn the MERN Stack?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Uses &lt;strong&gt;one programming language&lt;/strong&gt; — JavaScript — everywhere.&lt;/li&gt;
&lt;li&gt;Easy to scale and great for real-world apps.&lt;/li&gt;
&lt;li&gt;Huge community and lots of free learning resources.&lt;/li&gt;
&lt;li&gt;Used by startups, tech companies, and freelancers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your goal is to build a &lt;strong&gt;portfolio&lt;/strong&gt; that stands out, MERN projects are perfect.&lt;/p&gt;

&lt;h2&gt;
  
  
  MERN Architecture (How Everything Communicates)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmdi1r03lnsr3684yayyd.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%2Fmdi1r03lnsr3684yayyd.png" alt="MERN Stack Architecture" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Simple Example:
&lt;/h3&gt;

&lt;p&gt;User clicks &lt;strong&gt;Add Task&lt;/strong&gt; → React sends task to backend → Backend saves it in MongoDB → MongoDB stores → Backend sends confirmation → React updates screen.&lt;/p&gt;

&lt;p&gt;This cycle is the heart of MERN.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breakdown of Each Technology
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. MongoDB — The Database
&lt;/h3&gt;

&lt;p&gt;MongoDB stores data as &lt;strong&gt;documents&lt;/strong&gt; (similar to JSON):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Alice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isStudent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This format makes MongoDB &lt;strong&gt;easy to use with JavaScript&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Express.js — Handling APIs
&lt;/h3&gt;

&lt;p&gt;Express helps you create routes like:&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;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;/users&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;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;List of users&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;Express receives requests, processes logic, and sends responses.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. React.js — Building the UI
&lt;/h3&gt;

&lt;p&gt;React focuses on creating &lt;strong&gt;components&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Welcome&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Welcome&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;MERN&lt;/span&gt; &lt;span class="nx"&gt;Learning&lt;/span&gt;&lt;span class="o"&gt;!&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;React updates only the parts of the page that change — making apps feel fast.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Node.js — Runs Your Backend
&lt;/h3&gt;

&lt;p&gt;Node allows JavaScript to run &lt;strong&gt;outside the browser&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This starts your backend server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Typical MERN Folder Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;project/
│
├── client/           → React (Frontend)
│   ├── src/
│   └── package.json
│
├── server/           → Node + Express (Backend)
│   ├── models/       → MongoDB schemas
│   ├── routes/       → API endpoints
│   ├── server.js
│   └── package.json
│
└── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Separating frontend and backend keeps your project clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Concepts You Must Learn
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;REST APIs&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Your frontend talks to your backend using HTTP requests like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GET (read data)&lt;/li&gt;
&lt;li&gt;POST (send data)&lt;/li&gt;
&lt;li&gt;PUT (update data)&lt;/li&gt;
&lt;li&gt;DELETE (remove data)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;JSON Format&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This is how data travels between frontend and backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;State Management in React&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Examples: &lt;code&gt;useState&lt;/code&gt;, &lt;code&gt;useEffect&lt;/code&gt; hooks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic CRUD Example (Create, Read, Update, Delete)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Backend Route Example:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create Task&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;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;/tasks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="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="nx"&gt;newTask&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;Task&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;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="nx"&gt;text&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;newTask&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&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;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Task saved&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Frontend Fetch Example:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/tasks&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;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&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;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Learn MERN&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;h2&gt;
  
  
  Deploying a MERN App
&lt;/h2&gt;

&lt;p&gt;You can host:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt; on Vercel / Netlify&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt; on Render / Railway&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt; on MongoDB Atlas&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This lets your project become &lt;strong&gt;public&lt;/strong&gt; — great for portfolios.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning Roadmap (Beginner Friendly)
&lt;/h2&gt;

&lt;p&gt;Start with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript Basics&lt;/strong&gt; (functions, arrays, objects)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React Basics&lt;/strong&gt; (components, props, hooks)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node + Express&lt;/strong&gt; (API routes, server setup)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MongoDB&lt;/strong&gt; (CRUD operations)&lt;/li&gt;
&lt;li&gt;Build small projects (notes app, messenger, to-do app)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Practice is everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The MERN stack is powerful, modern, and &lt;strong&gt;approachable&lt;/strong&gt; — perfect for anyone learning full-stack development.&lt;/p&gt;

&lt;p&gt;Take it step-by-step, build consistently, and focus on &lt;strong&gt;understanding how data flows&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You're not just learning tools — you're learning how to &lt;strong&gt;build real applications&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding! 🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>mern</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
