<?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: henry messiah tmt</title>
    <description>The latest articles on DEV Community by henry messiah tmt (@henry_messiahtmt_099ca84).</description>
    <link>https://dev.to/henry_messiahtmt_099ca84</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3465565%2F03762155-0e93-4809-9802-adc7d72ea204.JPG</url>
      <title>DEV Community: henry messiah tmt</title>
      <link>https://dev.to/henry_messiahtmt_099ca84</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/henry_messiahtmt_099ca84"/>
    <language>en</language>
    <item>
      <title>Solidity to Compact: Developer's Migration Guide</title>
      <dc:creator>henry messiah tmt</dc:creator>
      <pubDate>Sat, 14 Feb 2026 09:45:42 +0000</pubDate>
      <link>https://dev.to/henry_messiahtmt_099ca84/solidity-to-compact-developers-migration-guide-1kij</link>
      <guid>https://dev.to/henry_messiahtmt_099ca84/solidity-to-compact-developers-migration-guide-1kij</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%2F640q4lkqras2lb6m4zr9.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%2F640q4lkqras2lb6m4zr9.png" alt="Header banner showing the title 'Solidity to Compact: A Developer's Migration Guide' with visual elements representing the transition from Ethereum's Solidity to Midnight's Compact language" width="800" height="285"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Many developers entering the &lt;a href="https://docs.midnight.network/" rel="noopener noreferrer"&gt;Midnight&lt;/a&gt; ecosystem bring valuable Solidity experience from Ethereum development. This guide bridges that knowledge gap by providing direct, side-by-side comparisons between Solidity and Compact code patterns.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.midnight.network/develop/reference/compact" rel="noopener noreferrer"&gt;Compact&lt;/a&gt; is Midnight Network's domain-specific language for building privacy-preserving smart contracts. Unlike Solidity's transparent-by-default model, Compact introduces explicit privacy controls through public ledger state and private witness functions. The language uses TypeScript-like syntax while introducing blockchain-specific concepts necessary for zero-knowledge proof generation.&lt;/p&gt;

&lt;p&gt;This comparison guide covers ten fundamental patterns that Solidity developers use daily: contract structure, data types, loops, state management, events, access control, visibility modifiers, initialization, validation, and privacy features. Each pattern includes working code examples in both languages, highlighting key differences and migration considerations.&lt;/p&gt;

&lt;p&gt;By mapping your existing Solidity knowledge to Compact equivalents, you will reduce the learning curve and start building privacy-preserving applications faster. The guide emphasizes not just syntax translation but conceptual differences in how privacy-first smart contracts operate.&lt;/p&gt;

&lt;p&gt;The image below shows the architecture comparison between Solidity and Compact.&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%2Frn3ljl88i1q86agl50wf.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%2Frn3ljl88i1q86agl50wf.png" alt="Architectural diagram comparing Solidity's contract-based structure on the left with Compact's ledger and circuit model on the right, illustrating the fundamental organizational differences between the two languages" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before diving into detailed code comparisons, let's start with a high-level overview of how common Solidity patterns map to their Compact equivalents.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick reference table
&lt;/h2&gt;

&lt;p&gt;This table provides an overview of how common Solidity patterns translate to Compact:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Solidity Feature&lt;/th&gt;
&lt;th&gt;Compact Equivalent&lt;/th&gt;
&lt;th&gt;Key Difference&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Structure&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;contract MyContract { }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;export ledger&lt;/code&gt; + &lt;code&gt;export circuit&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;No container; state declared globally&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Data Types&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Dynamic types, signed integers&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Field&lt;/code&gt;, &lt;code&gt;Bytes&amp;lt;N&amp;gt;&lt;/code&gt;, &lt;code&gt;Counter&lt;/code&gt;, &lt;code&gt;Boolean&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Fixed-size types required for ZK proofs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Loops&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;for (i &amp;lt; array.length)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;for&lt;/code&gt; with compile-time bounds&lt;/td&gt;
&lt;td&gt;Iteration limits must be known at compile time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Privacy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All public (even &lt;code&gt;private&lt;/code&gt; keyword)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;witness&lt;/code&gt; functions for true privacy&lt;/td&gt;
&lt;td&gt;Cryptographic privacy guarantees&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Events&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;emit Transfer(from, to, amount)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ledger state updates + return values&lt;/td&gt;
&lt;td&gt;Track changes via ledger counters and return values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Modifiers&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;modifier onlyOwner() { }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Helper circuits with &lt;code&gt;assert&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;No equivalent; use helper circuits instead&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Visibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;public&lt;/code&gt;, &lt;code&gt;external&lt;/code&gt;, &lt;code&gt;internal&lt;/code&gt;, &lt;code&gt;private&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;export&lt;/code&gt; vs non-exported&lt;/td&gt;
&lt;td&gt;File-scoped functions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Constructor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;constructor(params) { }&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;constructor(params)&lt;/code&gt; with direct assignment&lt;/td&gt;
&lt;td&gt;Similar syntax, explicit state initialization&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Validation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;require()&lt;/code&gt;, &lt;code&gt;revert()&lt;/code&gt;, &lt;code&gt;assert()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;assert()&lt;/code&gt; only&lt;/td&gt;
&lt;td&gt;Aborts circuit execution on failure&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;State Reading&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;function getValue() view&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Circuits read state directly&lt;/td&gt;
&lt;td&gt;External apps query via TypeScript indexer&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Now that you've seen the high-level mapping between Solidity and Compact, let's examine each pattern in detail with working code examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 1: Basic contract structure
&lt;/h2&gt;

&lt;p&gt;This section explores how Solidity and Compact organize code differently. You'll learn how Solidity bundles everything into contract containers, while Compact separates state declarations from transaction logic using a global ledger model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solidity: Contract declaration
&lt;/h3&gt;

&lt;p&gt;Solidity organizes code within contract containers that hold state variables and functions together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleStorage {
    // State variables declared inside contract
    uint256 public storedValue;
    address public owner;

    // Constructor initializes state
    constructor(uint256 _initialValue) {
        storedValue = _initialValue;
        owner = msg.sender;  // Automatic caller context
    }

    // State-modifying function
    function setValue(uint256 _newValue) public {
        storedValue = _newValue;
    }

    // View function for reading state
    function getValue() public view returns (uint256) {
        return storedValue;  // Direct state access
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This familiar Solidity pattern organizes everything within a contract container. Now, let's see how Compact approaches the same functionality with a fundamentally different structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compact: Ledger and circuit declaration
&lt;/h3&gt;

&lt;p&gt;Compact separates state declarations from transaction logic, with no container pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma language_version &amp;gt;= 0.18.0;
import CompactStandardLibrary;

// Public ledger state (declared globally, outside circuits)
export ledger stored_value: Field;
export ledger owner: Bytes&amp;lt;32&amp;gt;;

// Witness functions provide private off-chain data
witness get_caller(): Bytes&amp;lt;32&amp;gt;;

// Constructor initializes state with parameters
constructor(initial_value: Field, owner_address: Bytes&amp;lt;32&amp;gt;) {
    stored_value = initial_value;
    owner = owner_address;
}

// State-modifying circuit
export circuit set_value(new_value: Field): [] {
    stored_value = new_value;
}

// Circuits can read ledger state directly
export circuit get_and_update(increment: Field): Field {
    let current: Field = stored_value;  // Read state in circuit
    stored_value = current + increment;  // Update state
    return current;  // Return old value
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You've seen how Compact declares state and circuits differently from Solidity. Circuits can read and modify ledger state directly during execution. For external applications (like frontends) that need to query state without executing a circuit, you'll use the TypeScript runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reading ledger state in compact
&lt;/h3&gt;

&lt;p&gt;Compact circuits can read ledger state directly during execution. For external queries (like from a frontend), use TypeScript runtime:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// OPTION 1: Read state within a circuit (during execution)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;circuit&lt;/span&gt; &lt;span class="nf"&gt;check_value&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Field&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Field&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;stored_value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Direct state access&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// OPTION 2: Query state externally via TypeScript (for frontends)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;indexerPublicDataProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@midnight-ntwrk/midnight-js-indexer-public-data-provider&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;state&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;publicDataProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;queryContractState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contractAddress&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;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ledger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ContractModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stored_value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Read Field value&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentOwner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Value: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentValue&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, Owner: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentOwner&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that you've seen both implementations, let's highlight the critical differences you need to remember.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key differences
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Constructor initialization&lt;/strong&gt;: Both Solidity and Compact constructors accept parameters directly for initialization. In Compact, the constructor is called once during deployment with the initial state values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Privacy by default&lt;/strong&gt;: Solidity parameters are public. Compact circuit parameters can be provided as private witness data, enabling cryptographic privacy for sensitive inputs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structure&lt;/strong&gt;: Solidity uses a contract container holding all code. Compact declares ledger state globally and defines individual circuits for transactions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Language declaration&lt;/strong&gt;: Solidity specifies version with &lt;code&gt;pragma solidity ^0.8.0&lt;/code&gt;. Compact requires &lt;code&gt;pragma language_version&lt;/code&gt; with version specification and mandatory &lt;code&gt;import CompactStandardLibrary&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;State access&lt;/strong&gt;: Solidity allows state reads through view functions. Compact circuits can read ledger state directly during execution. External applications query state via TypeScript runtime SDK using the indexer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automatic context&lt;/strong&gt;: Solidity provides &lt;code&gt;msg.sender&lt;/code&gt; automatically. Compact requires explicit witness functions to access caller context.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Return types&lt;/strong&gt;: Solidity uses explicit return type syntax &lt;code&gt;returns (uint256)&lt;/code&gt;. Compact uses &lt;code&gt;[]&lt;/code&gt; (empty tuple) to indicate no return value, or specifies the return type like &lt;code&gt;Field&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With a solid understanding of how Compact structures contracts differently from Solidity, you're ready to explore another fundamental difference: the type system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 2: Data types and type system
&lt;/h2&gt;

&lt;p&gt;This section examines the fundamental differences in how each language handles data types. You'll discover why Solidity's flexible runtime sizing doesn't work in Compact's zero-knowledge proof environment, which requires all sizes to be known at compile time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solidity: Flexible types with runtime sizing
&lt;/h3&gt;

&lt;p&gt;Solidity supports various numeric types, signed integers, and dynamic data structures:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract DataTypes {
    // Boolean (no type suffix needed)
    bool public flag = true;

    // Unsigned integers (various sizes)
    uint256 public largeNumber = 1000000;
    uint8 public smallNumber = 255;

    // Signed integers supported
    int256 public signedNumber = -100;

    // Address type
    address public userAddress;

    // Fixed-size bytes
    bytes32 public dataHash;

    // Dynamic string (no size limit)
    string public name = "Example";

    // Dynamic array (grows at runtime)
    uint256[] public dynamicArray;

    // Fixed-size array
    uint256[5] public fixedArray;

    // Mapping (key-value store)
    mapping(address =&amp;gt; uint256) public balances;

    // Struct with dynamic fields
    struct User {
        string name;  // Dynamic
        uint256 age;
        bool active;
    }

    User public userData;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solidity's flexible type system allows for dynamic sizing and various numeric types. Compact takes a stricter approach, requiring compile-time bounds for proof generation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compact: Fixed-Size, unsigned types
&lt;/h3&gt;

&lt;p&gt;Compact requires compile-time sizing and primarily uses Field for general numeric operations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma language_version &amp;gt;= 0.18.0;
import CompactStandardLibrary;

// Numeric values - Field type for general numeric operations
export ledger number: Field;

// Specific unsigned integer types
export ledger small_number: Uint&amp;lt;8&amp;gt;;
export ledger medium_number: Uint&amp;lt;16&amp;gt;;
export ledger large_number: Uint&amp;lt;64&amp;gt;;

// Boolean values are available
export ledger flag: Boolean;

// Address type - use Bytes&amp;lt;32&amp;gt;
export ledger user_address: Bytes&amp;lt;32&amp;gt;;

// Fixed-size bytes
export ledger data_hash: Bytes&amp;lt;32&amp;gt;;

// Opaque string type (for dynamic strings)
export ledger name: Opaque&amp;lt;"string"&amp;gt;;

constructor() {
    number = 42;
    small_number = 255;
    medium_number = 1000;
    large_number = 1000000;
    flag = true;
    user_address = pad(32, "");
    data_hash = pad(32, "");
    name = "";
}

export circuit set_number(value: Field): [] {
    number = value;
}

export circuit set_flag(new_flag: Boolean): [] {
    flag = new_flag;
}

export circuit set_address(new_address: Bytes&amp;lt;32&amp;gt;): [] {
    user_address = new_address;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The contrast between these two approaches is stark. Let's break down what these differences mean for your migration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key differences
&lt;/h3&gt;

&lt;p&gt;The chart below visualizes the fundamental type system differences between Solidity's flexible runtime sizing and Compact's fixed compile-time bounds.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fop1qz79x8i34ompkoqvo.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%2Fop1qz79x8i34ompkoqvo.png" alt="Comparison chart showing data type differences: Solidity's flexible runtime sizing with signed integers versus Compact's fixed compile-time bounds with unsigned-only types" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Signed integers&lt;/strong&gt;: Solidity supports both &lt;code&gt;int&lt;/code&gt; and &lt;code&gt;uint&lt;/code&gt; types. Compact only provides unsigned integers (&lt;code&gt;Uint&amp;lt;8&amp;gt;&lt;/code&gt;, &lt;code&gt;Uint&amp;lt;16&amp;gt;&lt;/code&gt;, &lt;code&gt;Uint&amp;lt;32&amp;gt;&lt;/code&gt;, &lt;code&gt;Uint&amp;lt;64&amp;gt;&lt;/code&gt;, &lt;code&gt;Uint&amp;lt;128&amp;gt;&lt;/code&gt;, &lt;code&gt;Uint&amp;lt;256&amp;gt;&lt;/code&gt;). No negative numbers. The &lt;code&gt;Field&lt;/code&gt; type is commonly used for general numeric operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type specification&lt;/strong&gt;: Solidity infers types from literals (&lt;code&gt;0&lt;/code&gt;, &lt;code&gt;255&lt;/code&gt;, &lt;code&gt;true&lt;/code&gt;). Compact uses explicit type declarations in ledger fields and relies on type inference in circuit code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strings&lt;/strong&gt;: Solidity allows dynamic &lt;code&gt;string&lt;/code&gt; with unlimited length. Compact uses &lt;code&gt;Opaque&amp;lt;"string"&amp;gt;&lt;/code&gt; for dynamic strings or fixed-size arrays for bounded strings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Arrays&lt;/strong&gt;: Solidity supports both dynamic arrays (&lt;code&gt;uint[]&lt;/code&gt;) and fixed-size arrays (&lt;code&gt;uint[5]&lt;/code&gt;). Compact primarily uses fixed-size collections with compile-time known bounds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mappings&lt;/strong&gt;: Solidity provides key-value mappings with O(1) access. Compact has no direct mapping equivalent; use alternative data structures like MerkleTrees or Sets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structs&lt;/strong&gt;: Both languages support structured data. Solidity uses &lt;code&gt;struct&lt;/code&gt; keyword. Compact uses record types, and all fields must have fixed or opaque sizes.&lt;/p&gt;

&lt;p&gt;Now that you understand Compact's strict type requirements, let's examine how these constraints extend to one of the most common programming patterns: loops and iteration.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pattern 3: Loops and iteration
&lt;/h2&gt;

&lt;p&gt;This section reveals how loop constraints differ between the two languages. You'll understand why Compact requires compile-time bounds on all loops for proof circuit generation, unlike Solidity's dynamic iteration patterns.&lt;/p&gt;
&lt;h3&gt;
  
  
  Solidity: Dynamic loop bounds
&lt;/h3&gt;

&lt;p&gt;Solidity allows loops with runtime-determined iteration counts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract LoopExample {
    uint256[] public numbers;

    // For loop with dynamic bound (array.length)
    function sumArray() public view returns (uint256) {
        uint256 sum = 0;

        // Length determined at runtime
        for (uint256 i = 0; i &amp;lt; numbers.length; i++) {
            sum += numbers[i];
        }

        return sum;
    }

    // While loop with parameter-based bound
    function sumRange(uint256 max) public pure returns (uint256) {
        uint256 sum = 0;
        uint256 i = 0;

        // Max determined at runtime
        while (i &amp;lt; max) {
            sum += i;
            i++;  // Shorthand increment
        }

        return sum;
    }

    // Do-while loop
    function processUntilCondition(uint256 target) public pure returns (uint256) {
        uint256 value = 0;

        do {
            value += 10;
        } while (value &amp;lt; target);

        return value;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solidity's flexibility with loops makes iteration straightforward. Compact's zero-knowledge proof requirements demand a different approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compact: Compile-time bounded loops
&lt;/h3&gt;

&lt;p&gt;Compact requires all loops to have fixed maximum iteration counts known at compile time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma language_version &amp;gt;= 0.18.0;
import CompactStandardLibrary;

export ledger sum: Field;
export ledger counter: Counter;

constructor() {
    sum = 0;
}

// Loop with compile-time bound
export circuit sum_range(max: Field): [] {
    let total: Field = 0;

    // Compile-time maximum bound (100) with runtime condition
    for (let i: Field = 0; i &amp;lt; max &amp;amp;&amp;amp; i &amp;lt; 100; i = i + 1) {
        total = total + i;
    }

    sum = total;
}

// Counter operations for tracking
export circuit increment_counter(): [] {
    counter.increment(1);
}

export circuit increment_by_literal(): [] {
    // Counter.increment() requires literal integers
    counter.increment(5);  // Literal value
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These examples reveal fundamental differences in how the two languages handle iteration. Let's examine what this means for your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key differences
&lt;/h3&gt;

&lt;p&gt;The diagram below illustrates how Solidity's dynamic loop bounds differ from Compact's compile-time bounded iteration requirements.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc2iphu60kec052cd0ays.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%2Fc2iphu60kec052cd0ays.png" alt="Diagram illustrating loop bound differences: Solidity's dynamic runtime bounds versus Compact's compile-time constant maximum iteration requirements for zero-knowledge proof circuits" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loop bounds&lt;/strong&gt;: Solidity permits dynamic bounds like &lt;code&gt;i &amp;lt; array.length&lt;/code&gt; or parameter-based limits. Compact requires compile-time constant upper bounds (e.g., &lt;code&gt;i &amp;lt; 100&lt;/code&gt;) combined with runtime conditions using &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; operator.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Increment syntax&lt;/strong&gt;: Solidity supports shorthand operators &lt;code&gt;i++&lt;/code&gt; and &lt;code&gt;i--&lt;/code&gt;. Compact requires explicit assignment: &lt;code&gt;i = i + 1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loop types&lt;/strong&gt;: Solidity supports for, while, and do-while loops. Compact supports for and while loops only. No do-while.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero-knowledge requirement&lt;/strong&gt;: Loop bounds must be compile-time constants in Compact because zero-knowledge proof circuits require fixed, deterministic complexity. The proof system needs to know the maximum circuit size upfront.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workaround pattern&lt;/strong&gt;: When logical iteration count varies at runtime, use a compile-time maximum with conditional early exit using &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;. The loop always iterates the maximum times for the proof circuit, but can exit early with conditional logic.&lt;/p&gt;

&lt;p&gt;Having mastered bounded iteration, you're now ready to explore Compact's most powerful feature: true cryptographic privacy. This pattern reveals how Compact fundamentally differs from Solidity in handling sensitive data.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pattern 4: State variables (public vs private)
&lt;/h2&gt;

&lt;p&gt;This section uncovers the truth about blockchain privacy. You'll learn why Solidity's "private" keyword doesn't provide real privacy, and how Compact achieves genuine cryptographic privacy through witness functions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Solidity: Visibility modifiers (all data on-chain)
&lt;/h3&gt;

&lt;p&gt;Solidity uses visibility keywords, but all state exists on-chain regardless:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract StateExample {
    // Public (auto-generates getter function)
    uint256 public totalSupply;
    address public owner;

    // Private (no auto-getter, but still readable from blockchain)
    // Anyone can read this by directly accessing blockchain state
    uint256 private secretValue;

    // Internal (accessible to derived contracts)
    uint256 internal sharedValue;

    // Constant (compile-time immutable)
    uint256 public constant MAX_SUPPLY = 1000000;

    // Immutable (set once in constructor)
    address public immutable deployer;

    constructor() {
        owner = msg.sender;
        deployer = msg.sender;
        totalSupply = 0;
        secretValue = 12345;  // Still visible on-chain to anyone!
    }

    function updateSecret(uint256 _new) public {
        require(msg.sender == owner, "Not authorized");
        secretValue = _new;  // Written to blockchain, publicly readable
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Despite Solidity's private keyword, all blockchain state is publicly readable. Compact offers true cryptographic privacy through a completely different mechanism.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compact: Explicit privacy with witness functions
&lt;/h3&gt;

&lt;p&gt;Compact provides true cryptographic privacy through witness functions that supply off-chain data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma language_version &amp;gt;= 0.18.0;
import CompactStandardLibrary;

// Public ledger state (visible on-chain to everyone)
export ledger total_supply: Field;
export ledger owner: Bytes&amp;lt;32&amp;gt;;
export ledger deployer: Bytes&amp;lt;32&amp;gt;;
export ledger disclosed_secret: Field;

// Witness functions provide private off-chain data
witness get_secret_value(): Field;
witness get_caller(): Bytes&amp;lt;32&amp;gt;;

// Constants
const MAX_SUPPLY: Field = 1000000;

// Constructor with parameters for initialization
constructor(deployer_address: Bytes&amp;lt;32&amp;gt;, initial_supply: Field) {
    owner = deployer_address;
    deployer = deployer_address;
    total_supply = initial_supply;
    disclosed_secret = 0;
}

// Use private data without revealing it
export circuit use_secret_privately(): Field {
    let secret: Field = get_secret_value();
    let result: Field = secret + 100;
    return result;
}

// Selectively disclose private data (explicit opt-in)
export circuit update_secret(): [] {
    let caller: Bytes&amp;lt;32&amp;gt; = get_caller();
    let secret: Field = get_secret_value();
    assert(caller == owner, "Not authorized");
    disclosed_secret = secret;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The witness function declarations in the Compact code look simple, but you need to understand how to provide this private data from your TypeScript application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Witness function implementation (typescript side)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WalletBuilder&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@midnight-ntwrk/wallet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// When calling circuits, provide witnesses&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;witnesses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;get_secret_value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Return private value (never goes on-chain)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// BigInt value for Field&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;get_caller&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Return caller's address privately&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&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;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;state&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;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Call circuit with witnesses&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;callTx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use_secret_privately&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;witnesses&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you've seen both the Compact circuit code and the TypeScript witness implementation. Let's examine the fundamental privacy differences between these approaches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key differences
&lt;/h3&gt;

&lt;p&gt;The comparison below highlights the critical privacy differences between Solidity's publicly readable state and Compact's cryptographically private witness functions.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqfgot86bgqmw97rkbes0.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%2Fqfgot86bgqmw97rkbes0.png" alt="Side-by-side comparison showing Solidity's transparent-by-default model where all data is publicly readable versus Compact's explicit privacy model using witness functions for cryptographically private data" width="800" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Privacy model&lt;/strong&gt;: Solidity's &lt;code&gt;private&lt;/code&gt; keyword only affects Solidity-level visibility; anyone can read blockchain state directly using tools like Etherscan. Compact's &lt;code&gt;witness&lt;/code&gt; functions provide cryptographically private data that never appears on-chain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Witness functions&lt;/strong&gt;: Declared with &lt;code&gt;witness&lt;/code&gt; keyword, these functions retrieve private off-chain data. The data participates in zero-knowledge proof generation but remains hidden from the blockchain and all observers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Selective disclosure&lt;/strong&gt;: Compact allows explicit disclosure of private data to the public ledger. Without explicit disclosure (storing to a ledger field), witness data remains private forever.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;State reading&lt;/strong&gt;: Solidity generates automatic getters for public variables. Compact circuits can read ledger state directly during execution. External applications query state through the TypeScript runtime SDK via the indexer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constants&lt;/strong&gt;: Both languages support constants. Solidity uses &lt;code&gt;constant&lt;/code&gt; and &lt;code&gt;immutable&lt;/code&gt; keywords. Compact uses &lt;code&gt;const&lt;/code&gt; for compile-time constants.&lt;/p&gt;

&lt;p&gt;You've learned how Compact provides genuine privacy through witness functions. Next, let's address a common challenge developers face when migrating: how to track and monitor state changes without Solidity's event system.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pattern 5: Events and logging
&lt;/h2&gt;

&lt;p&gt;This section demonstrates how to track state changes without Solidity's event system. You'll learn Compact's alternative approach using ledger counters and return values for observable state transitions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Solidity: Event declaration and emission
&lt;/h3&gt;

&lt;p&gt;Solidity provides an explicit event system for off-chain logging:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract EventExample {
    // Event declarations with indexed parameters
    event Transfer(address indexed from, address indexed to, uint256 amount);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event StateChanged(uint256 indexed oldValue, uint256 indexed newValue);

    uint256 public value;
    address public owner;

    constructor() {
        owner = msg.sender;
        value = 0;
        // Emit event in constructor
        emit StateChanged(0, 0);
    }

    function updateValue(uint256 newValue) public {
        require(msg.sender == owner, "Not authorized");

        uint256 oldValue = value;
        value = newValue;

        // Explicitly emit event for off-chain tracking
        emit StateChanged(oldValue, newValue);
    }

    function transfer(address to, uint256 amount) public {
        // Transfer logic...

        // Event includes indexed and non-indexed data
        emit Transfer(msg.sender, to, amount);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solidity's dedicated event system makes off-chain tracking straightforward. Compact achieves similar observability through a different pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compact: Ledger state changes and return values
&lt;/h3&gt;

&lt;p&gt;Compact has no event system; observable changes occur through ledger updates and circuit return values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma language_version &amp;gt;= 0.18.0;
import CompactStandardLibrary;

export ledger value: Field;
export ledger owner: Bytes&amp;lt;32&amp;gt;;

// Counter fields for tracking changes (observable on ledger)
export ledger update_count: Counter;
export ledger transfer_count: Counter;

witness get_caller(): Bytes&amp;lt;32&amp;gt;;

constructor(initial_owner: Bytes&amp;lt;32&amp;gt;) {
    owner = initial_owner;
    value = 0;
}

// State changes are observable via ledger updates
export circuit update_value(new_value: Field): Field {
    let old_value: Field = value;  // Read current state
    value = new_value;              // Update state (observable)
    update_count.increment(1);      // Track change count

    // Return value provides event-like data
    return old_value;
}

export circuit transfer(to: Bytes&amp;lt;32&amp;gt;, amount: Field): [] {
    let from: Bytes&amp;lt;32&amp;gt; = get_caller();

    // Transfer logic...

    // Increment counter (observable on ledger)
    transfer_count.increment(1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ledger counters and return values provide observable data, but you need to know how to monitor these changes in your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitoring state changes (typescript side)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// TypeScript code for monitoring changes (not in .compact file)&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;indexerPublicDataProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@midnight-ntwrk/midnight-js-indexer-public-data-provider&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Subscribe to contract state changes&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;subscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;publicDataProvider&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribeToContractState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contractAddress&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&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;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ledger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ContractModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Monitor ledger changes&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Value: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Update count: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;update_count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Transfer count: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transfer_count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Build event-like timeline from state changes&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;With both patterns demonstrated, let's compare how each language handles state change tracking.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key differences
&lt;/h3&gt;

&lt;p&gt;The visualization below demonstrates how Compact's ledger-based state tracking replaces Solidity's dedicated event emission system.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbeky8r1lanx3o1061fgf.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%2Fbeky8r1lanx3o1061fgf.png" alt="Comparison diagram showing Solidity's dedicated event emission system with indexed parameters versus Compact's ledger-based state tracking using counters and return values" width="800" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Event system&lt;/strong&gt;: Solidity has dedicated &lt;code&gt;event&lt;/code&gt; keyword and &lt;code&gt;emit&lt;/code&gt; statement for logging. Compact has no event system; changes are tracked through ledger state updates, counter increments, and circuit return values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indexing&lt;/strong&gt;: Solidity allows &lt;code&gt;indexed&lt;/code&gt; parameters for efficient event filtering via logs. Compact applications must monitor ledger state changes via the indexer GraphQL API and filter off-chain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observability&lt;/strong&gt;: Solidity explicitly emits events with &lt;code&gt;emit EventName(params)&lt;/code&gt;. Compact circuit return values and ledger updates serve as observable outputs. Applications monitor these changes through the indexer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Off-chain tracking&lt;/strong&gt;: Solidity events are specifically designed for off-chain indexing with bloom filters and log queries. Compact applications monitor ledger state through the Midnight indexer and build event-like timelines from state changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Privacy&lt;/strong&gt;: Solidity events are always public and visible to everyone. Compact can selectively reveal information by choosing what to return from circuits or update in the ledger, keeping witness data private.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pattern recommendation&lt;/strong&gt;: To track state changes in Compact, maintain counter fields on the ledger (like &lt;code&gt;update_count&lt;/code&gt;) and return relevant data from circuits. Off-chain applications query the indexer to build event-like timelines from state transitions.&lt;/p&gt;

&lt;p&gt;With state monitoring strategies in place, let's turn our attention to a critical aspect of smart contract security: access control.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pattern 6: Access control and modifiers
&lt;/h2&gt;

&lt;p&gt;This section compares authorization patterns between the languages. You'll discover that Solidity's modifier syntax has no equivalent in Compact; instead, you use explicit helper circuit calls for authorization checks.&lt;/p&gt;
&lt;h3&gt;
  
  
  Solidity: Function modifiers
&lt;/h3&gt;

&lt;p&gt;Solidity uses modifiers to inject reusable authorization logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract AccessControl {
    address public owner;
    mapping(address =&amp;gt; bool) public admins;

    // Modifier for owner-only functions
    modifier onlyOwner() {
        require(msg.sender == owner, "Caller is not owner");
        _;  // Placeholder where function body executes
    }

    // Modifier for admin-only functions
    modifier onlyAdmin() {
        require(admins[msg.sender], "Caller is not admin");
        _;
    }

    // Modifier with parameters
    modifier hasMinBalance(uint256 minAmount) {
        require(address(this).balance &amp;gt;= minAmount, "Insufficient balance");
        _;
    }

    // Modifier for input validation
    modifier validAddress(address _addr) {
        require(_addr != address(0), "Invalid address");
        _;
    }

    constructor() {
        owner = msg.sender;
        admins[msg.sender] = true;
    }

    // Using modifiers (automatic injection before function)
    function transferOwnership(address newOwner) 
        public 
        onlyOwner           // Check 1: caller is owner
        validAddress(newOwner)  // Check 2: address is valid
    {
        owner = newOwner;
    }

    function addAdmin(address newAdmin) 
        public 
        onlyOwner 
        validAddress(newAdmin) 
    {
        admins[newAdmin] = true;
    }

    function adminAction() public onlyAdmin {
        // Admin-only logic
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solidity's modifier syntax provides elegant code reuse for authorization. Compact achieves the same security with a more explicit pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compact: Helper functions and assertions
&lt;/h3&gt;

&lt;p&gt;Compact has no modifier syntax; use helper functions with &lt;code&gt;assert&lt;/code&gt; statements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma language_version &amp;gt;= 0.18.0;
import CompactStandardLibrary;

export ledger owner: Bytes&amp;lt;32&amp;gt;;
export ledger admin_count: Counter;

witness get_caller(): Bytes&amp;lt;32&amp;gt;;

constructor(initial_owner: Bytes&amp;lt;32&amp;gt;) {
    owner = initial_owner;
}

// Helper function (replaces onlyOwner modifier)
// Call this at the start of circuits requiring owner access
circuit require_owner(caller: Bytes&amp;lt;32&amp;gt;): [] {
    assert(caller == owner, "Caller is not owner");
    // If assertion fails, circuit execution aborts
    // Transaction is never submitted to blockchain
}

// Helper function with parameters (replaces validAddress modifier)
circuit require_non_zero_address(addr: Bytes&amp;lt;32&amp;gt;): [] {
    const ZERO: Bytes&amp;lt;32&amp;gt; = pad(32, "");
    assert(addr != ZERO, "Invalid address");
}

// Using helper functions (manual calls replace modifiers)
export circuit transfer_ownership(new_owner: Bytes&amp;lt;32&amp;gt;): [] {
    let caller: Bytes&amp;lt;32&amp;gt; = get_caller();

    // Manually apply checks (like modifiers would)
    require_owner(caller);                    // Check 1
    require_non_zero_address(new_owner);      // Check 2

    // Function logic executes only if all checks pass
    owner = new_owner;
}

export circuit add_admin(): [] {
    let caller: Bytes&amp;lt;32&amp;gt; = get_caller();

    // Manual authorization checks
    require_owner(caller);

    // Simplified admin addition (just tracks count)
    admin_count.increment(1);
}

export circuit admin_action(): [] {
    let caller: Bytes&amp;lt;32&amp;gt; = get_caller();

    // Check owner status
    require_owner(caller);

    // Admin-only logic here
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both approaches secure your functions, but Compact has no modifier equivalent. All authorization checks must be done explicitly through helper circuit calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key differences
&lt;/h3&gt;

&lt;p&gt;The diagram below compares Solidity's automatic modifier injection with Compact's explicit helper function approach for authorization.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkbzi86w1ntnfqnmzijb6.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%2Fkbzi86w1ntnfqnmzijb6.png" alt="Flowchart comparing Solidity's automatic modifier injection pattern with Compact's explicit helper function approach for implementing authorization and access control" width="800" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Syntax&lt;/strong&gt;: Solidity has dedicated &lt;code&gt;modifier&lt;/code&gt; keyword with &lt;code&gt;_&lt;/code&gt; placeholder for automatic function body injection. Compact has no equivalent to modifiers; use explicit helper circuit calls at the start of circuits instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reusability&lt;/strong&gt;: Solidity modifiers automatically inject code before function execution with clean syntax. Compact has no modifier equivalent; you must manually call helper circuits in each circuit that needs authorization, giving explicit control but requiring more verbose code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Execution order&lt;/strong&gt;: Solidity modifiers execute in the order listed in function declaration. Compact has no modifiers; helper circuits execute in the exact order you call them, providing explicit control flow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caller context&lt;/strong&gt;: Solidity provides &lt;code&gt;msg.sender&lt;/code&gt; automatically in all functions. Compact requires witness functions like &lt;code&gt;get_caller()&lt;/code&gt; to retrieve the caller's address.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authorization logic&lt;/strong&gt;: Solidity uses &lt;code&gt;require()&lt;/code&gt; for authorization checks that revert on failure. Compact uses &lt;code&gt;assert()&lt;/code&gt; (similar to Solidity's &lt;code&gt;require&lt;/code&gt;) which aborts circuit execution if the condition fails, preventing the transaction from being submitted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authorization privacy&lt;/strong&gt;: Solidity authorization checks are publicly visible in transaction data. Compact can verify authorization privately through witness proofs without revealing the caller on-chain (unless explicitly disclosed to ledger state).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pattern recommendation&lt;/strong&gt;: Create a library of reusable helper circuits for common authorization checks (owner, admin, balance, etc.) and call them consistently at the start of circuits requiring access control.&lt;/p&gt;

&lt;p&gt;Having established secure access control patterns, let's examine how Compact handles function visibility and scope.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pattern 7: Function visibility
&lt;/h2&gt;

&lt;p&gt;This section clarifies how function visibility works in each language. You'll learn how Compact's simple export model replaces Solidity's four-level visibility system.&lt;/p&gt;
&lt;h3&gt;
  
  
  Solidity: Visibility modifiers
&lt;/h3&gt;

&lt;p&gt;Solidity provides four visibility levels and state access modifiers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract VisibilityExample {
    uint256 private internalState;

    // Public: callable externally and internally
    function publicFunction() public view returns (uint256) {
        return internalState;
    }

    // External: only callable from outside (more gas efficient)
    function externalFunction(uint256 value) external {
        internalState = value;
    }

    // Internal: callable within contract and derived contracts
    function internalFunction() internal view returns (uint256) {
        return internalState * 2;
    }

    // Private: only callable within this contract
    function privateFunction() private pure returns (uint256) {
        return 42;
    }

    // Pure: doesn't read or modify state
    function pureMath(uint256 a, uint256 b) public pure returns (uint256) {
        return a + b;
    }

    // View: reads but doesn't modify state
    function viewState() public view returns (uint256) {
        return internalState;
    }

    // Payable: can receive Ether
    function deposit() public payable {
        internalState += msg.value;
    }
}

// Inheritance example
contract DerivedExample is VisibilityExample {
    function callInternal() public view returns (uint256) {
        // Can call internal function from parent
        return internalFunction();
    }

    // Cannot call privateFunction() from parent
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solidity offers four distinct visibility levels with specific gas and inheritance implications. Compact simplifies this with a binary exported/non-exported model.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compact: Export keyword and circuit Scope
&lt;/h3&gt;

&lt;p&gt;Compact uses &lt;code&gt;export&lt;/code&gt; for public circuits; non-exported functions are internal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma language_version &amp;gt;= 0.18.0;
import CompactStandardLibrary;

export ledger internal_state: Field;

constructor() {
    internal_state = 0;
}

// Exported circuit: callable from outside
// Like Solidity's public/external
export circuit public_function(): Field {
    return internal_state;
}

// Exported circuit with state modification
export circuit external_function(value: Field): [] {
    internal_state = value;
}

// Non-exported function: internal to this file only
// Like Solidity's internal/private (no inheritance distinction)
circuit internal_helper(): Field {
    return internal_state * 2;
}

// Non-exported helper (private to file)
circuit private_helper(): Field {
    return 42;
}

// Pure computation (no state access)
// Like Solidity's pure functions
circuit pure_math(a: Field, b: Field): Field {
    return a + b;
}

// Exported circuit using helpers
export circuit complex_calculation(): Field {
    let internal_result: Field = internal_helper();
    let private_result: Field = private_helper();

    // Non-exported functions can be called within file
    return pure_math(internal_result, private_result);
}

// Circuit with state modification and return value
// No explicit "view" or "pure" keyword
export circuit update_and_return(new_value: Field): Field {
    let old_value: Field = internal_state;
    internal_state = new_value;
    return old_value;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The visibility systems reveal different design philosophies. Here's what you need to know for migration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key differences
&lt;/h3&gt;

&lt;p&gt;The chart below maps Solidity's four-level visibility system to Compact's simplified export-based model.&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%2F0ee9tzu6wmnhdpkqon68.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%2F0ee9tzu6wmnhdpkqon68.png" alt="Chart mapping Solidity's four-level visibility system (public, external, internal, private) to Compact's simplified two-level model using export keyword versus non-exported functions" width="800" height="534"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Visibility keywords&lt;/strong&gt;: Solidity has &lt;code&gt;public&lt;/code&gt;, &lt;code&gt;external&lt;/code&gt;, &lt;code&gt;internal&lt;/code&gt;, &lt;code&gt;private&lt;/code&gt;. Compact has &lt;code&gt;export&lt;/code&gt; for public circuits; non-exported functions are internal to the file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;External vs public&lt;/strong&gt;: Solidity distinguishes &lt;code&gt;external&lt;/code&gt; (more gas-efficient, calldata) from &lt;code&gt;public&lt;/code&gt; (can call internally, memory). Compact treats all exported circuits similarly without optimization difference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;State access modifiers&lt;/strong&gt;: Solidity has &lt;code&gt;view&lt;/code&gt; (read-only) and &lt;code&gt;pure&lt;/code&gt; (no state access). Compact has no explicit modifiers; circuits can both read and modify state directly. External applications also read state via TypeScript runtime SDK.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inheritance&lt;/strong&gt;: Solidity supports full inheritance with &lt;code&gt;internal&lt;/code&gt; functions accessible to derived contracts and &lt;code&gt;private&lt;/code&gt; functions not accessible. Compact has no inheritance model; use composition by importing circuits from other files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Payable functions&lt;/strong&gt;: Solidity uses &lt;code&gt;payable&lt;/code&gt; for functions that receive Ether. Compact has no native token handling within circuits; token operations are managed at the protocol level by the Midnight runtime.&lt;/p&gt;

&lt;p&gt;Understanding function visibility prepares you for the next essential pattern: contract initialization.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pattern 8: Contract initialization (constructors)
&lt;/h2&gt;

&lt;p&gt;This section explains contract initialization patterns in both languages. You'll understand how Compact's constructor works similarly to Solidity's but requires explicit parameter passing for context.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solidity: Constructor pattern
&lt;/h3&gt;

&lt;p&gt;Solidity uses the &lt;code&gt;constructor&lt;/code&gt; keyword for one-time initialization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Simple constructor with automatic context
contract SimpleConstructor {
    address public owner;
    uint256 public createdAt;

    constructor() {
        owner = msg.sender;          // Automatic
        createdAt = block.timestamp;  // Automatic
    }
}

// Constructor with parameters
contract ParameterizedConstructor {
    string public name;
    uint256 public totalSupply;
    address public admin;

    constructor(string memory _name, uint256 _supply) {
        name = _name;
        totalSupply = _supply;
        admin = msg.sender;  // Still automatic
    }
}

// Constructor with validation
contract ValidatedConstructor {
    address public owner;
    uint256 public initialSupply;

    uint256 public constant MAX_SUPPLY = 1000000;

    constructor(uint256 _supply) {
        // Validation with require
        require(_supply &amp;gt; 0, "Supply must be positive");
        require(_supply &amp;lt;= MAX_SUPPLY, "Supply exceeds maximum");

        owner = msg.sender;
        initialSupply = _supply;
    }
}

// Immutable variables (set once in constructor)
contract ImmutableExample {
    address public immutable deployer;
    uint256 public immutable deployTime;

    constructor() {
        deployer = msg.sender;
        deployTime = block.timestamp;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Solidity's constructor has special syntax and automatic context variables. Compact treats constructors similarly but requires explicit parameters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compact: Constructor circuit
&lt;/h3&gt;

&lt;p&gt;Compact uses a constructor that works similarly to Solidity, accepting parameters directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma language_version &amp;gt;= 0.18.0;
import CompactStandardLibrary;

// Simple constructor with parameters
export ledger owner: Bytes&amp;lt;32&amp;gt;;
export ledger created_at: Field;
export ledger total_supply: Field;

const MAX_SUPPLY: Field = 1000000;

constructor(
    initial_owner: Bytes&amp;lt;32&amp;gt;,
    timestamp: Field,
    supply: Field
) {
    // Validation using assert
    assert(supply &amp;gt; 0, "Supply must be positive");
    assert(supply &amp;lt;= MAX_SUPPLY, "Supply exceeds maximum");

    // Address validation
    const ZERO_BYTES: Bytes&amp;lt;32&amp;gt; = pad(32, "");
    assert(initial_owner != ZERO_BYTES, "Invalid owner");

    // Initialize state
    owner = initial_owner;
    created_at = timestamp;
    total_supply = supply;
}

// State-modifying circuits work with initialized state
export circuit update_supply(additional: Field): [] {
    assert(total_supply + additional &amp;lt;= MAX_SUPPLY, "Exceeds max supply");
    total_supply = total_supply + additional;
}

// Immutable fields (set once in constructor, never changed)
export ledger deployer: Bytes&amp;lt;32&amp;gt;; 
export ledger deploy_time: Field;

constructor(deployer_address: Bytes&amp;lt;32&amp;gt;, timestamp: Field) {
    deployer = deployer_address;
    deploy_time = timestamp;
    // Application logic should prevent further changes to these fields
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The constructor looks straightforward, but you need to understand how to call it correctly during deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Constructor call in deployment script
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// TypeScript deployment code&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;deployContract&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@midnight-ntwrk/midnight-js-contracts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Get wallet state for address&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&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;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;state&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Deploy with constructor parameters&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deployed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;deployContract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contractInstance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// Pass constructor arguments directly&lt;/span&gt;
    &lt;span class="na"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;initial_owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;BigInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
        &lt;span class="na"&gt;supply&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;privateStateId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;contractState&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;initialPrivateState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Deployed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deployTxData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contractAddress&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that you've seen both the contract code and deployment script, let's examine the key differences in initialization patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key differences
&lt;/h3&gt;

&lt;p&gt;The illustration below shows how constructor patterns differ between Solidity's special syntax and Compact's regular circuit approach.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F63qomc6o7n8lyndv685a.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%2F63qomc6o7n8lyndv685a.png" alt="Diagram comparing Solidity's special constructor syntax with automatic context variables versus Compact's regular circuit approach requiring explicit parameters from deployment scripts" width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Constructor pattern&lt;/strong&gt;: Both Solidity and Compact use constructors that accept parameters directly. The syntax and initialization approach are similar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caller Context&lt;/strong&gt;: Solidity provides &lt;code&gt;msg.sender&lt;/code&gt; and &lt;code&gt;block.timestamp&lt;/code&gt; automatically in constructors. Compact requires these values as explicit constructor parameters, passed from the deployment script.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validation&lt;/strong&gt;: Solidity uses &lt;code&gt;require()&lt;/code&gt; for constructor validation that reverts deployment if failed. Compact uses &lt;code&gt;assert()&lt;/code&gt;, which aborts circuit execution if validation fails.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inheritance&lt;/strong&gt;: Solidity constructors can call parent constructors with special syntax. Compact has no inheritance; cannot chain constructor calls. Use composition patterns instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Immutability&lt;/strong&gt;: Solidity uses &lt;code&gt;immutable&lt;/code&gt; keyword for values set once in constructor. Compact has no built-in immutability enforcement for ledger fields; implement "set-once" patterns in your application logic if needed.&lt;/p&gt;

&lt;p&gt;With initialization patterns covered, let's address a critical aspect of robust smart contract development: input validation and error handling.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pattern 9: Input validation and error handling
&lt;/h2&gt;

&lt;p&gt;This section compares validation mechanisms between the languages. You'll learn why Compact uses only assert() statements that prevent proof generation.&lt;/p&gt;
&lt;h3&gt;
  
  
  Solidity: Require, revert, and assert
&lt;/h3&gt;

&lt;p&gt;Solidity provides three mechanisms for validation and error handling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;contract ValidationExample {
    address public owner;
    uint256 public balance;

    constructor() {
        owner = msg.sender;
    }

    // Using require for input validation (common pattern)
    function deposit(uint256 amount) public {
        require(amount &amp;gt; 0, "Amount must be positive");
        require(amount &amp;lt;= 1000000, "Amount exceeds maximum");

        balance += amount;
        // If requires fail, transaction reverts and gas refunded
    }

    // Multiple require statements
    function withdraw(uint256 amount) public {
        require(msg.sender == owner, "Not authorized");
        require(amount &amp;gt; 0, "Invalid amount");
        require(balance &amp;gt;= amount, "Insufficient balance");

        balance -= amount;
        // State changes only persist if all requires pass
    }

    // Using revert for complex conditions
    function complexValidation(address user, uint256 value) public {
        if (user == address(0)) {
            revert("Invalid user address");
        }

        if (value &amp;lt; 100 || value &amp;gt; 10000) {
            revert("Value out of range");
        }

        // Process transaction only if validations pass
    }

    // Assert for invariants (should never fail in correct code)
    function criticalOperation(uint256 a, uint256 b) public pure returns (uint256) {
        uint256 result = a + b;
        assert(result &amp;gt;= a);  // Check overflow
        return result;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The diagram below illustrates Solidity's three validation mechanisms (require, revert, assert) and their different behaviors.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtpdaap6ynf0df3ww2hv.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%2Fgtpdaap6ynf0df3ww2hv.png" alt="Flowchart showing Solidity's three validation mechanisms: require for input validation, revert for complex conditions, and assert for invariant checking, with their different gas refund behaviors" width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Solidity provides three validation mechanisms with different behaviors. Compact simplifies this to a single assertion pattern.&lt;/p&gt;
&lt;h3&gt;
  
  
  Compact: Assert statements only
&lt;/h3&gt;

&lt;p&gt;Compact uses &lt;code&gt;assert()&lt;/code&gt; statements that abort circuit execution when validation fails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma language_version &amp;gt;= 0.18.0;
import CompactStandardLibrary;

export ledger owner: Bytes&amp;lt;32&amp;gt;;
export ledger balance: Field;

witness get_caller(): Bytes&amp;lt;32&amp;gt;;

constructor(initial_owner: Bytes&amp;lt;32&amp;gt;) {
    owner = initial_owner;
    balance = 0;
}

// Using assert for input validation
export circuit deposit(amount: Field): [] {
    assert(amount &amp;gt; 0, "Amount must be positive");
    assert(amount &amp;lt;= 1000000, "Amount exceeds maximum");

    balance = balance + amount;
    // If assertions fail, circuit execution aborts
}

// Multiple assert statements
export circuit withdraw(amount: Field): [] {
    let caller: Bytes&amp;lt;32&amp;gt; = get_caller();

    assert(caller == owner, "Not authorized");
    assert(amount &amp;gt; 0, "Invalid amount");
    assert(balance &amp;gt;= amount, "Insufficient balance");

    balance = balance - amount;
    // State changes only persist if all assertions pass
}

// Complex validation with conditional logic
export circuit complex_validation(user: Bytes&amp;lt;32&amp;gt;, value: Field): [] {
    const ZERO: Bytes&amp;lt;32&amp;gt; = pad(32, "");
    assert(user != ZERO, "Invalid user address");

    assert(value &amp;gt;= 100 &amp;amp;&amp;amp; value &amp;lt;= 10000, "Value out of range");

    // Process transaction only if validations pass
}

// Return status codes for recoverable errors
// (alternative pattern when you don't want to abort)
export circuit withdraw_with_status(amount: Field): Field {
    let caller: Bytes&amp;lt;32&amp;gt; = get_caller();

    // Check conditions and return status codes
    if (caller != owner) {
        return 1;  // Error code: unauthorized
    }

    if (balance &amp;lt; amount) {
        return 2;  // Error code: insufficient balance
    }

    balance = balance - amount;
    return 0;  // Success code
}

// Compact has no try-catch
// Design with status codes or boolean returns for error cases
export circuit safe_operation(): Boolean {
    // Return true for success, false for failure
    // instead of throwing errors

    // Perform operation
    return true;  // Success
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The visualization below demonstrates how Compact's single assert mechanism prevents proof generation when validation fails.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbeyrgnjcm1l37x85mqgy.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%2Fbeyrgnjcm1l37x85mqgy.png" alt="Diagram illustrating Compact's single assert mechanism that prevents zero-knowledge proof generation when validation fails, with no on-chain transaction submission for failed assertions" width="800" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The single assertion mechanism requires a different approach to error handling. Here are the critical differences.&lt;/p&gt;
&lt;h3&gt;
  
  
  Key differences
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Validation mechanism&lt;/strong&gt;: Solidity has &lt;code&gt;require()&lt;/code&gt;, &lt;code&gt;revert()&lt;/code&gt;, and &lt;code&gt;assert()&lt;/code&gt; with different gas behaviors and use cases. Compact only has &lt;code&gt;assert()&lt;/code&gt; for validation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error handling&lt;/strong&gt;: Solidity's failed validations revert transactions and return error messages to callers. Compact's failed assertions abort circuit execution, preventing the transaction from being created and submitted to the blockchain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transaction costs&lt;/strong&gt;: Solidity failed validations consume gas up to the failure point, then refund remaining. Compact failed assertions prevent transaction submission entirely, so no on-chain cost occurs for validation failures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error messages&lt;/strong&gt;: Solidity error messages are returned to callers and visible on explorers. Compact error messages are for developers during testing; assertions either pass or fail without revealing error details on-chain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recovery&lt;/strong&gt;: Solidity exceptions can be caught with try-catch for error recovery patterns. Compact has no exception handling; design with status codes or boolean returns for scenarios where you want to handle failures gracefully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best practice&lt;/strong&gt;: Use &lt;code&gt;assert()&lt;/code&gt; for critical validations that must never fail in correct usage (invariants, authorization). For recoverable errors (like insufficient balance), return status codes or boolean success flags instead of asserting, allowing applications to handle errors gracefully.&lt;/p&gt;

&lt;p&gt;You've now mastered nine fundamental patterns that have direct Solidity equivalents. For our final pattern, we'll explore Compact's unique privacy features.&lt;/p&gt;
&lt;h2&gt;
  
  
  Pattern 10: Privacy-specific features (compact-only)
&lt;/h2&gt;

&lt;p&gt;This section showcases Compact's unique privacy capabilities that have no Solidity equivalent. You'll explore zero-knowledge proof patterns that enable genuinely private computation.&lt;/p&gt;

&lt;p&gt;The diagram below illustrates the zero-knowledge proof flow that enables Compact's privacy features, showing how witness data participates in proof generation without appearing on-chain.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnl65r7dnu9bcy8dpj8x.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%2Fgnl65r7dnu9bcy8dpj8x.png" alt="Process flow diagram showing how witness data participates in off-chain zero-knowledge proof generation without appearing on-chain, with only the verification proof submitted to the blockchain" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important note&lt;/strong&gt;: The examples in this pattern demonstrate privacy concepts. Specific cryptographic functions may vary based on the CompactStandardLibrary version. Always refer to the official Compact documentation for exact API details.&lt;/p&gt;
&lt;h3&gt;
  
  
  Private state with witness functions
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma language_version &amp;gt;= 0.18.0;
import CompactStandardLibrary;

// Public ledger (visible on-chain to everyone)
export ledger public_counter: Field;
export ledger disclosed_value: Field;
export ledger computation_result: Field;

// Witness functions (private off-chain data)
// These provide private inputs that never appear on-chain
witness get_secret_value(): Field;

constructor() {
    public_counter = 0;
    disclosed_value = 0;
    computation_result = 0;
}

// Example 1: Private computation with public result
export circuit compute_privately(): [] {
    // get_secret_value() retrieves private input
    let secret: Field = get_secret_value();  // Private

    // Compute with private data
    // The computation happens in the proof, but secret never goes on-chain
    let result: Field = secret * 2 + 100;

    // Store result publicly (secret remains hidden)
    computation_result = result;
}

// Example 2: Selective disclosure
export circuit reveal_secret(): [] {
    let secret: Field = get_secret_value();  // Private

    // Explicitly choose to disclose private data
    // This is the only way to make witness data public
    disclosed_value = secret;
    public_counter = public_counter + 1;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;These examples showcase powerful privacy patterns. Let's summarize the key concepts that make them possible.&lt;/p&gt;
&lt;h3&gt;
  
  
  Key privacy concepts
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Witness functions&lt;/strong&gt;: Declared with &lt;code&gt;witness&lt;/code&gt; keyword, these provide private off-chain data that participates in zero-knowledge proof generation but never appears on-chain. The blockchain only sees the proof, not the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Selective disclosure&lt;/strong&gt;: Private data remains hidden unless explicitly written to a ledger field. You control what becomes public and what stays private, enabling granular privacy controls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commitments and Merkle Trees&lt;/strong&gt;: Compact provides &lt;code&gt;MerkleTree&lt;/code&gt; and &lt;code&gt;HistoricMerkleTree&lt;/code&gt; types for storing commitments to private data. These allow proving membership without revealing which specific item is being proven.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Privacy patterns&lt;/strong&gt;: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prove properties without revealing data&lt;/strong&gt;: Prove you're over 18 without showing birthdate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit to values without disclosure&lt;/strong&gt;: Sealed-bid auctions where bids are hidden until reveal phase&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Selective disclosure timing&lt;/strong&gt;: Keep data private during sensitive periods, reveal later&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anonymous actions&lt;/strong&gt;: Private operations where identity stays hidden&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;No Solidity equivalent&lt;/strong&gt;: These patterns are impossible in Solidity because all transaction data, inputs, and state changes are public and visible on-chain. Compact's zero-knowledge proof architecture enables genuinely private computation where only the proof of correct execution is public.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Zero-knowledge proofs&lt;/strong&gt;: When a circuit executes, it generates a zero-knowledge proof that proves "I executed this code correctly with some private inputs" without revealing what those inputs were. The blockchain verifies the proof but never sees the private data.&lt;/p&gt;
&lt;h2&gt;
  
  
  Key conceptual differences
&lt;/h2&gt;

&lt;p&gt;This section moves beyond syntax to explore the architectural differences that drive language design choices.&lt;/p&gt;
&lt;h3&gt;
  
  
  Privacy model
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Solidity&lt;/strong&gt;: Everything is public by default. The &lt;code&gt;private&lt;/code&gt; keyword only affects Solidity-level visibility; anyone can read blockchain state directly using block explorers or archive nodes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compact&lt;/strong&gt;: Explicit public/private separation. Ledger state is public and visible to everyone. Witness functions provide truly private data through zero-knowledge proofs that cryptographically guarantee privacy.&lt;/p&gt;

&lt;p&gt;The comparison below visualizes how Solidity's transparent-by-default model differs fundamentally from Compact's explicit public/private separation.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Femthk2dp6uk98solnt2g.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%2Femthk2dp6uk98solnt2g.png" alt="Architectural comparison illustrating Solidity's transparent-by-default approach where all state is publicly readable versus Compact's explicit public/private separation using ledger state and witness functions" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Execution model
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Solidity&lt;/strong&gt;: Code executes directly on-chain in the Ethereum Virtual Machine. Every node re-executes transactions. Gas costs are proportional to computational complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compact&lt;/strong&gt;: Code compiles to zero-knowledge circuits. Proofs generate off-chain using private data. Only the proof is submitted on-chain. On-chain validation has constant cost regardless of computation complexity.&lt;/p&gt;

&lt;p&gt;The diagram below illustrates the architectural difference between Solidity's on-chain execution and Compact's off-chain proof generation with on-chain verification.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3iuxl2fdtyrpgrrdzmcr.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%2F3iuxl2fdtyrpgrrdzmcr.png" alt="System architecture diagram comparing Solidity's on-chain execution in the EVM where every node re-executes transactions versus Compact's off-chain proof generation with constant-time on-chain verification" width="800" height="473"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  State management
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Solidity&lt;/strong&gt;: State variables declared inside contracts. Functions directly read and write state using simple assignment and access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compact&lt;/strong&gt;: Ledger state declared globally with &lt;code&gt;export ledger&lt;/code&gt;. Circuits can both read and modify state through direct assignments. External applications query state via TypeScript runtime SDK using the indexer.&lt;/p&gt;
&lt;h3&gt;
  
  
  Data constraints
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Solidity&lt;/strong&gt;: Supports dynamic arrays that grow at runtime, unbounded loops based on array length, runtime-sized strings, and signed integers for negative numbers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compact&lt;/strong&gt;: Requires compile-time bounds on most data structures. Only unsigned integers supported (no negative numbers). All sizes must be known at compile time for proof circuit generation. Uses &lt;code&gt;Opaque&amp;lt;"string"&amp;gt;&lt;/code&gt; for dynamic strings.&lt;/p&gt;

&lt;p&gt;The chart below summarizes the fundamental data constraint differences between Solidity's dynamic runtime flexibility and Compact's fixed compile-time requirements.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxs8ipni7i1pdspb2vkcq.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%2Fxs8ipni7i1pdspb2vkcq.png" alt="Table comparing data constraints: Solidity's support for dynamic arrays, unbounded loops, and signed integers versus Compact's requirement for compile-time bounds, fixed-size structures, and unsigned-only integers" width="800" height="553"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Caller context
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Solidity&lt;/strong&gt;: &lt;code&gt;msg.sender&lt;/code&gt; automatically provides transaction sender. &lt;code&gt;block.timestamp&lt;/code&gt;, &lt;code&gt;block.number&lt;/code&gt;, &lt;code&gt;msg.value&lt;/code&gt; etc. automatically available in all functions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compact&lt;/strong&gt;: Caller address retrieved via witness functions for privacy. Block data passed as circuit parameters from deployment/interaction scripts. Nothing is automatic; everything is explicit.&lt;/p&gt;
&lt;h3&gt;
  
  
  Migration mindset
&lt;/h3&gt;

&lt;p&gt;When migrating from Solidity to Compact, shift your thinking:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;From transparent to privacy-first&lt;/strong&gt;: Default to keeping data private, explicitly disclose only when necessary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;From dynamic to bounded&lt;/strong&gt;: Determine maximum sizes for data structures upfront, or use &lt;code&gt;Opaque&lt;/code&gt; types for dynamic data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;From runtime to compile-time&lt;/strong&gt;: Most constraints must be expressible at compile time for circuit generation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;From automatic to explicit&lt;/strong&gt;: Explicitly handle caller context, timestamps, and authorization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;From gas optimization to proof optimization&lt;/strong&gt;: Minimize proof complexity rather than gas costs.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Common pitfalls and solutions
&lt;/h2&gt;

&lt;p&gt;This section identifies the seven most common mistakes developers make during migration. You'll learn practical solutions to avoid these pitfalls and accelerate your Compact development.&lt;/p&gt;

&lt;p&gt;The diagram below highlights the six most common migration pitfalls developers encounter when converting Solidity contracts to Compact.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hedbepg4fho9nm3hmcz.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%2F9hedbepg4fho9nm3hmcz.png" alt="Visual checklist highlighting seven common migration pitfalls: forgetting type suffixes, using dynamic sizes, unbounded loops, missing library imports, using signed integers, and expecting automatic msg.sender" width="800" height="611"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Pitfall 1: Incorrect return type syntax
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong&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;export circuit increment(): Void {  // Outdated syntax
    counter.increment(1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Correct&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;export circuit increment(): [] {  // Modern syntax
    counter.increment(1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Use &lt;code&gt;[]&lt;/code&gt; (empty tuple) for circuits that don't return values. This is the modern Compact syntax.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pitfall 2: Using dynamic sizes without Opaque
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong&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;export ledger name: String;  // No size specified
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Correct&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;export ledger name: Opaque&amp;lt;"string"&amp;gt;;  // Dynamic string using Opaque
// OR
export ledger name: Bytes&amp;lt;100&amp;gt;;  // Fixed maximum size
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Use &lt;code&gt;Opaque&amp;lt;"string"&amp;gt;&lt;/code&gt; for dynamic strings or specify fixed sizes with &lt;code&gt;Bytes&amp;lt;N&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pitfall 3: Unbounded loops
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong&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;export circuit process_all(count: Field): [] {
    for (let i: Field = 0; i &amp;lt; count; i = i + 1) {
        // Loop bound depends on runtime parameter
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Correct&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;export circuit process_all(count: Field): [] {
    // Add compile-time maximum bound
    for (let i: Field = 0; i &amp;lt; count &amp;amp;&amp;amp; i &amp;lt; 1000; i = i + 1) {
        // Now compiler knows maximum 1000 iterations
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Always add compile-time upper bounds to loops using &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; operator.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pitfall 4: Forgetting CompactStandardLibrary import
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong&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;pragma language_version &amp;gt;= 0.18.0;
// Missing import
export ledger value: Field;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Correct&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;pragma language_version &amp;gt;= 0.18.0;
import CompactStandardLibrary;  // Required
export ledger value: Field;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Always include &lt;code&gt;import CompactStandardLibrary;&lt;/code&gt; after the pragma.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pitfall 5: Using signed integers
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong&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;export ledger temperature: Int32;  // No signed types
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Correct&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;export ledger temperature: Field;  // Use Field for general numeric values
// Handle negative logic differently using conditional checks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Compact only has unsigned integers and Field. Redesign logic to avoid negative numbers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pitfall 6: Expecting automatic msg.sender
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong&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;export circuit restricted_action(): [] {
    assert(msg.sender == owner, "Not authorized");  // Doesn't exist
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Correct&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;witness get_caller(): Bytes&amp;lt;32&amp;gt;;

export circuit restricted_action(): [] {
    let caller: Bytes&amp;lt;32&amp;gt; = get_caller();  // Explicit witness
    assert(caller == owner, "Not authorized");
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Use witness functions to get caller address. Provide the address from TypeScript when calling the circuit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pitfall 7: Using disclose() incorrectly
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Wrong (for regular types)&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;export circuit update_value(new_value: Field): [] {
    stored_value = disclose(new_value);  // Not needed for regular types
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Correct (for regular types)&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;export circuit update_value(new_value: Field): [] {
    stored_value = new_value;  // Direct assignment
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Correct (for Opaque types)&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;export circuit store_message(msg: Opaque&amp;lt;"string"&amp;gt;): [] {
    message = disclose(msg);  // Required for Opaque types
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;: Regular types (Field, Bytes, Boolean, Uint) can be assigned directly to ledger fields. Opaque types like Opaque&amp;lt;"string"&amp;gt; require disclose() to make the data public on the ledger, as Compact treats user inputs as private by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complete migration Example
&lt;/h2&gt;

&lt;p&gt;Let's migrate a simple ERC20-like token contract from Solidity to Compact, applying all the patterns you've learned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solidity token contract
&lt;/h3&gt;

&lt;p&gt;The diagram below provides a visual overview of the Solidity ERC20-like token contract structure before migration.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkw6tvjyfsoizx08nyptd.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%2Fkw6tvjyfsoizx08nyptd.png" alt="Architecture diagram of a Solidity ERC20-like token contract showing the contract structure with state variables, events, modifiers, and functions organized within a single container" width="800" height="638"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleToken {
    string public name = "SimpleToken";
    string public symbol = "STK";
    uint256 public totalSupply;
    address public owner;

    mapping(address =&amp;gt; uint256) public balances;

    event Transfer(address indexed from, address indexed to, uint256 amount);
    event Mint(address indexed to, uint256 amount);

    constructor(uint256 _initialSupply) {
        owner = msg.sender;
        totalSupply = _initialSupply;
        balances[owner] = _initialSupply;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    function transfer(address to, uint256 amount) public returns (bool) {
        require(balances[msg.sender] &amp;gt;= amount, "Insufficient balance");
        require(to != address(0), "Invalid recipient");

        balances[msg.sender] -= amount;
        balances[to] += amount;

        emit Transfer(msg.sender, to, amount);
        return true;
    }

    function mint(address to, uint256 amount) public onlyOwner {
        require(to != address(0), "Invalid recipient");

        totalSupply += amount;
        balances[to] += amount;

        emit Mint(to, amount);
    }

    function balanceOf(address account) public view returns (uint256) {
        return balances[account];
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This standard ERC20-like contract uses familiar Solidity patterns. Now let's see the Compact equivalent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compact token contract
&lt;/h3&gt;

&lt;p&gt;The visualization below shows the migrated Compact token contract structure with ledger state, circuits, and witness functions.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft22c2sd3ivpijewoe7z9.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%2Ft22c2sd3ivpijewoe7z9.png" alt="Architecture diagram of a migrated Compact token contract showing global ledger state declarations, witness functions for private data, and separate circuit functions replacing the Solidity contract structure" width="800" height="677"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pragma language_version &amp;gt;= 0.18.0;
import CompactStandardLibrary;

// Public ledger state
export ledger total_supply: Field;
export ledger owner: Bytes&amp;lt;32&amp;gt;;
export ledger owner_balance: Field;
export ledger transfer_count: Counter;
export ledger mint_count: Counter;

witness get_caller(): Bytes&amp;lt;32&amp;gt;;

constructor(initial_supply: Field, owner_address: Bytes&amp;lt;32&amp;gt;) {
    total_supply = initial_supply;
    owner = owner_address;
    owner_balance = initial_supply;
}

// Helper function (replaces onlyOwner modifier)
circuit require_owner(caller: Bytes&amp;lt;32&amp;gt;): [] {
    assert(caller == owner, "Not owner");
}

// Helper function for address validation
circuit require_valid_address(addr: Bytes&amp;lt;32&amp;gt;): [] {
    const ZERO: Bytes&amp;lt;32&amp;gt; = pad(32, "");
    assert(addr != ZERO, "Invalid recipient");
}

// Transfer circuit
export circuit transfer(to: Bytes&amp;lt;32&amp;gt;, amount: Field): [] {
    let caller: Bytes&amp;lt;32&amp;gt; = get_caller();

    // Validation
    require_valid_address(to);
    assert(owner_balance &amp;gt;= amount, "Insufficient balance");

    // Update balances (simplified - only tracks owner balance)
    owner_balance = owner_balance - amount;

    // Increment counter (replaces event)
    transfer_count.increment(1);
}

// Mint circuit
export circuit mint(amount: Field): [] {
    let caller: Bytes&amp;lt;32&amp;gt; = get_caller();

    // Authorization and validation
    require_owner(caller);

    // Update state
    total_supply = total_supply + amount;
    owner_balance = owner_balance + amount;

    // Increment counter (replaces event)
    mint_count.increment(1);
}

// Read balance through circuit
export circuit get_balance(): Field {
    return owner_balance;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Typescript deployment script
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;deployContract&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@midnight-ntwrk/midnight-js-contracts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;WalletBuilder&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@midnight-ntwrk/wallet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Build wallet&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wallet&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;WalletBuilder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;buildFromSeed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;indexerUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;indexerWsUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;proofServerUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;nodeUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;walletSeed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;networkId&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;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Wait for sync&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;firstValueFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;state&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;syncProgress&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;synced&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Get wallet address&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;firstValueFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;wallet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;state&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// Deploy contract&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deployed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;deployContract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contractInstance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;privateStateId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tokenState&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;initialPrivateState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
    &lt;span class="na"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;initial_supply&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;owner_address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&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="s2"&gt;`Deployed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;deployed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deployTxData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;contractAddress&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Typescript interaction script
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;findDeployedContract&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@midnight-ntwrk/midnight-js-contracts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;indexerPublicDataProvider&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@midnight-ntwrk/midnight-js-indexer-public-data-provider&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Connect to deployed contract&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deployed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;findDeployedContract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;contractAddress&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;deploymentAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;contractInstance&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;privateStateId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tokenState&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;initialPrivateState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Read balance&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;state&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;publicDataProvider&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;queryContractState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;contractAddress&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;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ledger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;TokenModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Owner balance: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;owner_balance&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Total supply: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ledger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;total_supply&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Call transfer&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;witnesses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;get_caller&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;walletState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&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;tx&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;deployed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;callTx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;transfer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;recipientAddress&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;witnesses&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Transfer completed: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;txId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Call mint (owner only)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mintTx&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;deployed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;callTx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;get_caller&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;walletState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;address&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="s2"&gt;`Minted: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;mintTx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;txId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The diagram below summarizes the eight critical migration decisions made during the ERC20 conversion from Solidity to Compact.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq8vedpjjrotyclki7pye.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%2Fq8vedpjjrotyclki7pye.png" alt="Process flow diagram showing the complete lifecycle of a Compact contract: deployment with TypeScript scripts, circuit interaction with witness data, and state reading via the indexer API" width="800" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You've now seen the complete migration including contract code, deployment, and interaction. Let's highlight the critical migration decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key migration points
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No mapping&lt;/strong&gt;: Compact has no mapping type. This example uses simplified single-balance tracking. Production code needs alternative patterns like MerkleTrees for managing multiple balances.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No events&lt;/strong&gt;: Use counters on the ledger and return values. Applications monitor state changes via indexer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Explicit context&lt;/strong&gt;: No &lt;code&gt;msg.sender&lt;/code&gt;. Use witness functions to provide caller address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Constructor parameters&lt;/strong&gt;: Compact constructors accept parameters directly, similar to Solidity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Return types&lt;/strong&gt;: Use &lt;code&gt;[]&lt;/code&gt; for circuits with no return value (modern Compact syntax).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Balance reading&lt;/strong&gt;: Circuits can read state directly. External applications also read state via TypeScript using indexer queries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Modifiers&lt;/strong&gt;: Use helper circuits with &lt;code&gt;assert()&lt;/code&gt; instead of modifiers, called explicitly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Witness providers&lt;/strong&gt;: TypeScript provides witness data when calling circuits.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Validation&lt;/strong&gt;: Use &lt;code&gt;assert()&lt;/code&gt; for validation. Failed assertions abort circuit execution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;State access&lt;/strong&gt;: Circuits can read and write ledger state directly during execution.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  When to use each language
&lt;/h2&gt;

&lt;p&gt;This section provides strategic guidance for choosing the right language for your project. You'll learn when Compact's privacy features are essential, when Solidity's mature ecosystem is better, and when a hybrid approach makes sense.&lt;/p&gt;

&lt;p&gt;Understanding the strengths of each language helps you choose appropriately.&lt;/p&gt;

&lt;p&gt;Let's start by examining scenarios where Compact's privacy features make it the superior choice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose compact when
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Privacy is essential&lt;/strong&gt;: Applications requiring confidential data processing, private transactions, or selective information disclosure.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Healthcare records with HIPAA compliance requirements&lt;/li&gt;
&lt;li&gt;Confidential voting systems&lt;/li&gt;
&lt;li&gt;Private financial transactions&lt;/li&gt;
&lt;li&gt;Sealed-bid auctions where bid amounts must stay hidden&lt;/li&gt;
&lt;li&gt;Identity verification without revealing personal information&lt;/li&gt;
&lt;li&gt;KYC compliance with data protection regulations&lt;/li&gt;
&lt;li&gt;Private supply chain tracking&lt;/li&gt;
&lt;li&gt;Confidential credit scoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Regulatory compliance&lt;/strong&gt;: Industries with strict data privacy regulations that prohibit public data storage or require selective disclosure controls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Selective disclosure&lt;/strong&gt;: Scenarios requiring proof of properties without revealing underlying data.&lt;/p&gt;

&lt;p&gt;The chart below illustrates use cases where Compact's privacy features provide essential value that Solidity cannot match.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqsbef3axtdkcqimfspne.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%2Fqsbef3axtdkcqimfspne.png" alt="Decision matrix showing use cases where Compact is superior: privacy-essential applications, regulatory compliance scenarios, confidential voting, sealed-bid auctions, and selective disclosure requirements" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Choose solidity when
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Full transparency required&lt;/strong&gt;: Applications benefiting from complete auditability and public verification where privacy is not needed.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Public treasuries and transparent fund management&lt;/li&gt;
&lt;li&gt;Open governance systems and DAO voting&lt;/li&gt;
&lt;li&gt;Transparent token distributions&lt;/li&gt;
&lt;li&gt;Decentralized exchanges with public order books&lt;/li&gt;
&lt;li&gt;Community-funded projects requiring full accountability&lt;/li&gt;
&lt;li&gt;Public records and registries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Complex DeFi composability&lt;/strong&gt;: Applications requiring integration with existing Ethereum protocols.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dynamic structures essential&lt;/strong&gt;: Applications needing runtime-determined data structures or signed integers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mature ecosystem critical&lt;/strong&gt;: Projects requiring extensive battle-tested libraries and established auditing processes.&lt;/p&gt;

&lt;p&gt;The visualization below shows scenarios where Solidity's transparency and mature ecosystem make it the superior choice.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fibt27b8uo7g1366inmfz.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%2Fibt27b8uo7g1366inmfz.png" alt="Decision matrix showing use cases where Solidity is superior: full transparency requirements" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Hybrid approach
&lt;/h3&gt;

&lt;p&gt;Consider using both languages in a single application architecture:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pattern&lt;/strong&gt;: Use Solidity for public coordination and Compact for private operations, connected via cross-chain bridges.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Private NFT marketplace&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Solidity contracts manage public NFT ownership records&lt;/li&gt;
&lt;li&gt;Compact contracts handle private bid amounts and confidential buyer identities&lt;/li&gt;
&lt;li&gt;Public can verify ownership, but bid details stay private&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The diagram below demonstrates how hybrid architectures can combine Solidity's public coordination with Compact's private operations for optimal results.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4srpt7ww4ohtejh9c44f.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%2F4srpt7ww4ohtejh9c44f.png" alt="Hybrid architecture: solidity + compact integration" width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional resources
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Official documentation
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Midnight Network Docs&lt;/strong&gt;: &lt;a href="https://docs.midnight.network" rel="noopener noreferrer"&gt;https://docs.midnight.network&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compact Language Reference&lt;/strong&gt;: &lt;a href="https://docs.midnight.network/develop/reference/compact" rel="noopener noreferrer"&gt;https://docs.midnight.network/develop/reference/compact&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Midnight API&lt;/strong&gt;: &lt;a href="https://docs.midnight.network/develop/reference/midnight-api" rel="noopener noreferrer"&gt;https://docs.midnight.network/develop/reference/midnight-api&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Getting Started Tutorial&lt;/strong&gt;: &lt;a href="https://docs.midnight.network/develop/tutorial" rel="noopener noreferrer"&gt;https://docs.midnight.network/develop/tutorial&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tools and platforms
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compact Compiler&lt;/strong&gt;: &lt;a href="https://github.com/midnightntwrk/compact" rel="noopener noreferrer"&gt;https://github.com/midnightntwrk/compact&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lace Wallet&lt;/strong&gt;: &lt;a href="https://www.lace.io" rel="noopener noreferrer"&gt;https://www.lace.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example Counter DApp&lt;/strong&gt;: &lt;a href="https://github.com/midnightntwrk/example-counter" rel="noopener noreferrer"&gt;https://github.com/midnightntwrk/example-counter&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Example Bulletin Board DApp&lt;/strong&gt;: &lt;a href="https://github.com/midnightntwrk/example-bboard" rel="noopener noreferrer"&gt;https://github.com/midnightntwrk/example-bboard&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Community
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Discord&lt;/strong&gt;: &lt;a href="https://discord.com/invite/midnightnetwork" rel="noopener noreferrer"&gt;https://discord.com/invite/midnightnetwork&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Twitter/X&lt;/strong&gt;: @MidnightNtwrk&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/midnightntwrk" rel="noopener noreferrer"&gt;https://github.com/midnightntwrk&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Your Solidity expertise provides a strong foundation for Compact development. The core concepts of state management, transactions, and contract logic transfer directly. What's new is the explicit privacy model and the constraints of zero-knowledge proof systems.&lt;/p&gt;

&lt;p&gt;With the patterns, differences, and examples outlined in this guide, you are ready to build the next generation of privacy-preserving decentralized applications on Midnight Network. Start with simple contracts, gradually add privacy features, and explore the unique capabilities that zero-knowledge proofs enable.&lt;/p&gt;

&lt;p&gt;Privacy is not just a feature, it's a fundamental design principle. Compact gives you the tools to build applications where users control their data, sensitive information stays confidential, and trust is established through cryptographic proofs rather than transparency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Privacy Architecture&lt;/strong&gt;: Ledger for public state, witness functions for truly private data with cryptographic guarantees&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compile-Time Constraints&lt;/strong&gt;: Fixed sizes for most structures, bounded loops, unsigned integers - all determined before execution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Direct Equivalents&lt;/strong&gt;: Mappings, inheritance, events require alternative patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicit Context&lt;/strong&gt;: Manual handling of caller context and timestamps through witness functions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proof-Aware Design&lt;/strong&gt;: Optimize for proof complexity and generation time rather than gas costs&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Welcome to privacy-first smart contract development.&lt;/p&gt;

</description>
      <category>web3</category>
      <category>solidity</category>
      <category>tutorial</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>The Pharmacist's Guide to Becoming a Developer: Skills That Transfer</title>
      <dc:creator>henry messiah tmt</dc:creator>
      <pubDate>Fri, 31 Oct 2025 13:40:54 +0000</pubDate>
      <link>https://dev.to/henry_messiahtmt_099ca84/the-pharmacists-guide-to-becoming-a-developer-skills-that-transfer-3f1l</link>
      <guid>https://dev.to/henry_messiahtmt_099ca84/the-pharmacists-guide-to-becoming-a-developer-skills-that-transfer-3f1l</guid>
      <description>&lt;p&gt;I remember staring at my first &lt;code&gt;for loop&lt;/code&gt; error at 2 AM, feeling completely lost. Six months earlier, I had been confidently counseling patients on complex drug interactions, calculating pediatric doses, and navigating the intricacies of pharmaceutical care. Now, I couldn't figure out why my JavaScript code kept returning &lt;code&gt;undefined&lt;/code&gt;. Had I made a terrible mistake transitioning to programming?&lt;/p&gt;

&lt;p&gt;That moment of doubt was transformative. As I methodically worked through the problem, isolating variables, checking each line, testing different inputs, something clicked. This process felt remarkably familiar. I was troubleshooting code the same way I had troubleshooted medication errors: systematically, carefully, with attention to detail.&lt;/p&gt;

&lt;p&gt;Two years later, I work as a software developer and technical writer, and I've come to realize something crucial: my pharmacy background didn't hold me back from programming. It made me better at it.&lt;/p&gt;

&lt;p&gt;If you're a healthcare professional considering a transition to tech, this article is for you. I'm not going to tell you what you need to learn; there are thousands of tutorials for that. Instead, I want to show you what you already have: a sophisticated set of problem-solving skills that translate directly into programming excellence. You're not starting from scratch. You're building on years of expertise.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Myth of "Starting From Scratch"
&lt;/h2&gt;

&lt;p&gt;When I first decided to learn programming, I was bombarded with discouraging narratives. "You're too old to learn coding." "You don't have a computer science degree." "You need to think like a programmer, which means forgetting everything you know."&lt;/p&gt;

&lt;p&gt;These misconceptions are not just wrong, they're harmful. They create unnecessary barriers and fuel imposter syndrome before you even write your first line of code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here's the reality&lt;/strong&gt;: programming is fundamentally about problem-solving, not memorizing syntax. While computer science degrees teach valuable theory, the tech industry increasingly recognizes that diverse backgrounds bring unique perspectives and strengths. According to Course Report's 2023 Bootcamp Graduate Survey, career changers make up over 70% of coding bootcamp students, and they perform just as well as, if not better than traditional CS graduates in many roles.&lt;/p&gt;

&lt;p&gt;Healthcare professionals, in particular, bring something invaluable to software development: experience solving high-stakes problems in complex systems. When I build applications now, I draw on years of clinical decision-making, risk assessment, and systematic thinking. These aren't skills you can pick up in a weekend tutorial. They take years to develop, and you've already done that work.&lt;/p&gt;

&lt;p&gt;The question isn't whether you can learn to code. It's how you'll leverage your existing expertise to become an exceptional developer.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Seven Skills That Transfer
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Systematic Problem-Solving
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;In Pharmacy:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As a pharmacist, I approached every medication-related problem with a structured methodology. When a patient experienced adverse effects, I didn't guess randomly, I followed a systematic process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gather complete information (medication history, timeline, symptoms)&lt;/li&gt;
&lt;li&gt;Identify potential causes using differential diagnosis&lt;/li&gt;
&lt;li&gt;Prioritize possibilities based on likelihood and severity&lt;/li&gt;
&lt;li&gt;Test hypotheses by checking drug interactions, dosages, and patient factors&lt;/li&gt;
&lt;li&gt;Implement solutions and monitor outcomes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is algorithmic thinking in its purest form. We used clinical algorithms for antibiotic selection, dosage calculations based on renal function, and decision trees for managing drug interactions. SOAP notes (Subjective, Objective, Assessment, Plan) provided a framework for documenting this process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Programming:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Debugging code follows an identical pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gather information (error messages, console logs, input values)&lt;/li&gt;
&lt;li&gt;Identify potential causes (logic errors, syntax issues, incorrect data types)&lt;/li&gt;
&lt;li&gt;Prioritize based on error messages and code flow&lt;/li&gt;
&lt;li&gt;Test hypotheses by isolating code sections and using debugging tools&lt;/li&gt;
&lt;li&gt;Implement fixes and verify the solution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consider this parallel:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pharmacy Scenario:&lt;/strong&gt; A patient on warfarin presents with unexpected bleeding. I check their medication list and discover they recently started taking a new supplement containing high-dose vitamin E, which increases bleeding risk when combined with warfarin. Solution: discontinue the supplement and adjust warfarin dosing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Programming Scenario:&lt;/strong&gt; A React application crashes with a "Cannot read property of undefined" error. I check the code flow and discover that an API call sometimes returns &lt;code&gt;null&lt;/code&gt;, and the component tries to access properties of that null value before checking if data exists. Solution: add conditional rendering and proper null checks.&lt;/p&gt;

&lt;p&gt;The cognitive process is identical: systematic investigation, pattern recognition, and logical solution implementation.&lt;/p&gt;

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

&lt;p&gt;Early in my coding journey, I spent hours trying to debug an authentication issue. Users could log in, but their session data wasn't persisting. I was ready to blame the entire authentication library when I remembered my pharmaceutical training: always check the obvious first, like you'd verify a patient's adherence before adjusting medication.&lt;/p&gt;

&lt;p&gt;I went back to basics, checked environment variables, reviewed configuration files, and examined database connections. The culprit? A typo in the session secret key in my production environment. Five minutes of systematic checking solved what I'd been randomly poking at for hours. My pharmacy training had taught me to follow the evidence, not my assumptions.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Attention to Detail
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;In Pharmacy:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In pharmaceutical care, attention to detail isn't just important; it's literally life or death. A misplaced decimal point means the difference between 1.0 mg and 10 mg, between therapeutic effect and toxicity. I reviewed hundreds of prescriptions, checking for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Correct drug names (many drugs have similar names: Hydralazine vs. Hydroxyzine)&lt;/li&gt;
&lt;li&gt;Appropriate dosages for patient age, weight, and condition&lt;/li&gt;
&lt;li&gt;Drug allergies and contraindications&lt;/li&gt;
&lt;li&gt;Potential drug-drug, drug-food, and drug-disease interactions&lt;/li&gt;
&lt;li&gt;Subtle discrepancies in patient records&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This vigilance becomes second nature. You learn to catch the pharmacist's equivalent of syntax errors, such as an order for metformin in a patient with severe renal impairment, or a dose of acetaminophen that exceeds maximum daily limits when combined with other medications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Programming:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Code demands similar precision. A missing semicolon, a typo in a variable name, or an off-by-one error can break an entire application. But beyond syntax errors, attention to detail manifests in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code review practices:&lt;/strong&gt; Catching logic errors before they reach production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Input validation:&lt;/strong&gt; Anticipating edge cases and invalid data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing thoroughness:&lt;/strong&gt; Writing test cases that cover boundary conditions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security considerations:&lt;/strong&gt; Recognizing potential vulnerabilities in authentication, data handling, and API endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pharmacy mindset of "measure twice, cut once" translates perfectly to writing production code. I'm meticulous about testing edge cases because I understand that small oversights can cascade into major failures. When I write a function that processes user data, I don't just test the happy path; I test what happens with null values, empty strings, unexpected data types, and malicious inputs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-World Connection:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Just as I would never dispense medication without triple-checking the label, patient name, and dosage, I never deploy code without thorough testing and review. This might seem tedious to some developers, but to me, it's a professional responsibility. In pharmacy, we had a saying: "You're only as good as your last error." In software development, especially in production environments, this principle holds equally true.&lt;/p&gt;

&lt;p&gt;My attention to detail has made me particularly effective in QA testing and technical writing, where catching inconsistencies and edge cases is crucial.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Documentation &amp;amp; Record-Keeping
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;In Pharmacy:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Documentation was a cornerstone of pharmaceutical care. Every patient interaction required clear, comprehensive records:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SOAP notes:&lt;/strong&gt; Structured documentation of clinical reasoning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medication counseling records:&lt;/strong&gt; What was explained, patient understanding, concerns addressed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intervention documentation:&lt;/strong&gt; What problem was identified, action taken, outcome&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handoff notes:&lt;/strong&gt; Critical information for the next pharmacist on duty&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good documentation served multiple purposes: continuity of care, legal protection, quality assurance, and communication with other healthcare providers. I learned to write notes that were clear, concise, and comprehensive, balancing detail with readability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Programming:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These documentation skills transfer seamlessly to software development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code comments:&lt;/strong&gt; Explaining complex logic or non-obvious design decisions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;README files:&lt;/strong&gt; Project setup, usage instructions, and architectural overview&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API documentation:&lt;/strong&gt; Endpoints, parameters, response formats, and example usage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commit messages:&lt;/strong&gt; Clear descriptions of what changed and why&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technical documentation:&lt;/strong&gt; User guides, troubleshooting resources, and system architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key principle is the same: your documentation should allow someone else to understand and continue your work without you present. In pharmacy, I documented so the next pharmacist could pick up seamlessly. In programming, I document so future developers (including future me) can understand the codebase.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actionable Tip:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many companies desperately need technical writers who understand both the subject matter and how to communicate clearly. Pharmacists excel at translating complex information into plain language—we spent years explaining medications to patients with varying health literacy levels. This skill makes healthcare-background developers particularly valuable for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating user-facing documentation&lt;/li&gt;
&lt;li&gt;Writing API guides for external developers&lt;/li&gt;
&lt;li&gt;Building internal knowledge bases&lt;/li&gt;
&lt;li&gt;Contributing to open-source documentation&lt;/li&gt;
&lt;li&gt;Transitioning into developer advocacy roles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Technical writing can also be a lucrative side income or even a full career pivot. I currently earn additional income writing technical tutorials and documentation for SaaS companies, directly leveraging the documentation skills I developed in pharmacy.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Continuous Learning
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;In Pharmacy:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pharmacy requires lifelong learning. New drugs receive FDA approval regularly, clinical guidelines are updated constantly, and evidence-based practice evolves with new research. As a pharmacist, I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Completed continuing education (CE) requirements annually&lt;/li&gt;
&lt;li&gt;Read clinical studies and drug information updates&lt;/li&gt;
&lt;li&gt;Attended seminars on new therapeutic approaches&lt;/li&gt;
&lt;li&gt;Learned new pharmacy software systems and technologies&lt;/li&gt;
&lt;li&gt;Stayed current on insurance formulary changes and regulations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This wasn't optional; it was integral to maintaining competence and licensure. I became comfortable with being a perpetual student, knowing that my education would never be "complete."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Programming:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The tech industry moves even faster than healthcare. JavaScript frameworks rise and fall in popularity within years. Libraries update with breaking changes. Best practices evolve. New languages emerge. The parallel to pharmacy is striking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learning new frameworks and libraries as projects require&lt;/li&gt;
&lt;li&gt;Following industry blogs, documentation updates, and release notes&lt;/li&gt;
&lt;li&gt;Adapting to rapidly changing best practices&lt;/li&gt;
&lt;li&gt;Self-directed learning through courses, tutorials, and documentation&lt;/li&gt;
&lt;li&gt;Staying current on security vulnerabilities and patches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Mindset Shift:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many career changers feel overwhelmed by how much there is to learn in programming. But here's the reframe that transformed my perspective: &lt;em&gt;I don't need to learn to learn, I already know how to learn complex systems quickly.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In pharmacy school, I memorized thousands of drug names, mechanisms, interactions, and dosing protocols. I learned to interpret lab values, understand disease pathophysiology, and apply clinical guidelines. If I could learn that the cytochrome P450 3A4 enzyme metabolizes over 50% of marketed drugs and understand the clinical implications of enzyme induction and inhibition, I could learn React hooks.&lt;/p&gt;

&lt;p&gt;The skills that helped me pass pharmacy board exams, breaking complex topics into manageable chunks, using spaced repetition, teaching concepts to solidify understanding, and applying knowledge through practice problems, work just as well for mastering programming.&lt;/p&gt;

&lt;p&gt;When I approach a new technology now, I use the same strategies I used for learning new drug classes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start with fundamentals:&lt;/strong&gt; Understand core concepts before diving into advanced features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build mental models:&lt;/strong&gt; Create analogies and frameworks for how things work&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learn by doing:&lt;/strong&gt; Theory matters, but hands-on practice solidifies understanding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Teach others:&lt;/strong&gt; Explaining concepts reveals gaps in my knowledge&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review regularly:&lt;/strong&gt; Spaced repetition prevents knowledge decay&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The difference between pharmacy and programming isn't the volume of learning required; it's that in programming, the information is more accessible, the feedback is immediate, and you can experiment without risking patient safety.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Working with Complex Systems
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;In Pharmacy:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pharmaceutical care involves navigating incredibly complex, interconnected systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pharmacokinetics and pharmacodynamics:&lt;/strong&gt; How drugs move through the body (absorption, distribution, metabolism, excretion) and how they produce therapeutic effects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drug interactions:&lt;/strong&gt; Understanding how multiple medications interact, sometimes enhancing effects, sometimes causing dangerous combinations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-system thinking:&lt;/strong&gt; Recognizing how cardiovascular medications affect renal function, or how diabetes impacts wound healing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insurance formularies:&lt;/strong&gt; Navigating Byzantine rules about what medications are covered under different plans&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Healthcare coordination:&lt;/strong&gt; Interfacing between patients, physicians, insurance companies, and other healthcare providers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every decision required systems thinking. Prescribing an antibiotic isn't just about killing bacteria; it's about considering renal function (affects dosing), drug allergies (contraindications), current medications (interactions), patient adherence patterns (complexity of regimen), and insurance coverage (accessibility).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Programming:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Software systems share this complexity:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Architecture:&lt;/strong&gt; Understanding how frontend, backend, database, and external services interact&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependencies:&lt;/strong&gt; Managing libraries that depend on other libraries, and how updates cascade&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data flow:&lt;/strong&gt; Tracing how information moves through an application, from user input to database storage to API responses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging across systems:&lt;/strong&gt; Identifying whether an issue originates in the frontend code, backend logic, database queries, or network communication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration:&lt;/strong&gt; Making different services work together, each with its own requirements and constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Visual Comparison:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider how similar these flows are:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Drug Pathway Through the Body:&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;Oral medication → GI absorption → Liver metabolism → Systemic circulation → 
Target tissue → Therapeutic effect → Renal/hepatic elimination
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Data Flow Through an Application:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User input → Frontend validation → API request → Backend processing → 
Database query → Data transformation → API response → UI update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both require understanding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entry points and validation&lt;/li&gt;
&lt;li&gt;Transformation processes&lt;/li&gt;
&lt;li&gt;Target destinations&lt;/li&gt;
&lt;li&gt;Expected outputs&lt;/li&gt;
&lt;li&gt;Error handling at each stage&lt;/li&gt;
&lt;li&gt;Feedback mechanisms&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;When I built my first full-stack application, a medication tracking app. I instinctively approached the architecture the same way I approached patient care plans. I mapped out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input layer&lt;/strong&gt; (frontend): Like taking a patient history&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validation layer&lt;/strong&gt; (backend): Like checking for contraindications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Processing layer&lt;/strong&gt; (business logic): Like applying clinical guidelines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage layer&lt;/strong&gt; (database): Like maintaining medical records&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring layer&lt;/strong&gt; (logging/alerts): Like follow-up appointments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This systems thinking, honed through years of pharmaceutical care, made architectural concepts intuitive rather than abstract. I understood that changing one part of the system could have cascading effects elsewhere, just like adjusting one medication in a patient's regimen might require adjusting others.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Communication with Non-Technical Stakeholders
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;In Pharmacy:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the most underappreciated pharmacy skills is the ability to translate complex medical information into language that patients understand. Every day, I explained:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How medications work, without overwhelming patients with biochemistry&lt;/li&gt;
&lt;li&gt;Potential side effects, balancing information with avoiding unnecessary anxiety&lt;/li&gt;
&lt;li&gt;Why drug interactions matter, in concrete rather than abstract terms&lt;/li&gt;
&lt;li&gt;Insurance denials and prior authorization processes, helping patients navigate bureaucracy&lt;/li&gt;
&lt;li&gt;Treatment alternatives when first-line options weren't suitable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also communicated regularly with other healthcare professionals, physicians who needed pharmacokinetic consultation, nurses implementing medication orders, and insurance companies requiring clinical justification. Each audience required a different language, detail level, and framing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Programming:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These same communication skills are invaluable in software development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Explaining technical concepts to non-technical team members:&lt;/strong&gt; Product managers, designers, marketers, executives&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Writing user-friendly error messages:&lt;/strong&gt; Not "Error 422: Unprocessable Entity" but "Please enter a valid email address"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Presenting technical solutions to business stakeholders:&lt;/strong&gt; Translating implementation details into business value&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creating end-user documentation:&lt;/strong&gt; Guides that users can actually follow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaborating across disciplines:&lt;/strong&gt; Working with designers who think visually, product managers who think strategically, and clients who think about outcomes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Career Advantage:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This skill set makes healthcare-background developers particularly valuable in:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Client-facing roles:&lt;/strong&gt; Many developers struggle to communicate technical concepts to clients. I can discuss database architecture with engineers in the morning and explain the same system's benefits to a non-technical client in the afternoon.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Technical writing:&lt;/strong&gt; As mentioned earlier, clear communication is scarce in tech. Good documentation is often the difference between a product's success and failure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Developer advocacy:&lt;/strong&gt; Companies need people who can represent their products to developer communities, explain features, create tutorials, and gather feedback. Communication skills are essential.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Product management:&lt;/strong&gt; Understanding both technical constraints and user needs allows for better product decisions. Many healthcare professionals transition successfully into product management roles.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Team leadership:&lt;/strong&gt; Senior developers and tech leads spend more time communicating than coding. The ability to explain technical decisions, mentor junior developers, and interface with stakeholders becomes crucial.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Personal Story:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;During a project meeting, our team was debating whether to implement a complex caching strategy. The engineers understood the technical benefits, but the project manager worried about the timeline impact, and the client didn't understand why it mattered.&lt;/p&gt;

&lt;p&gt;I drew on my pharmacy communication skills. To the project manager, I explained it like medication adherence: "Just like how pre-packaging medications in blister packs saves time during administration, this caching strategy takes extra setup time now but makes every subsequent operation faster." To the client, I framed it in business terms: "This will reduce your server costs by approximately 40% and improve page load times, which directly impacts user retention."&lt;/p&gt;

&lt;p&gt;Both analogies worked because I understood the principle (caching) and could translate it into language that resonated with each audience. This skill was developed through years of counseling patients and has become one of my most valuable professional assets.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Quality Assurance &amp;amp; Risk Management
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;In Pharmacy:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pharmacy is fundamentally about risk management. Every medication has potential benefits and potential harms, and pharmacists constantly evaluate risk-benefit ratios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Double-checking calculations:&lt;/strong&gt; Especially for high-risk populations like pediatrics and neonates, where dosing errors are most dangerous&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implementing safety checks:&lt;/strong&gt; Multiple verification points before dispensing medication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anticipating adverse effects:&lt;/strong&gt; "What could go wrong?" thinking before problems occur&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High-alert medications:&lt;/strong&gt; Extra safeguards for drugs with narrow therapeutic indices or high risk of harm&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Root cause analysis:&lt;/strong&gt; When errors occurred, a systematic investigation to prevent recurrence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We learned to think defensively. What if the patient forgets to take this medication? What if they take it with food when they shouldn't? What if they're taking an unreported supplement that interacts? This anticipatory thinking prevented problems before they arose.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In Programming:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Software development requires identical risk management:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unit testing:&lt;/strong&gt; Verifying that individual functions work correctly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration testing:&lt;/strong&gt; Ensuring different parts of the application work together&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error handling:&lt;/strong&gt; Anticipating and gracefully managing failures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Input validation:&lt;/strong&gt; Defending against invalid or malicious data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge case testing:&lt;/strong&gt; What happens with empty arrays, null values, or unexpected data types?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security considerations:&lt;/strong&gt; Protecting against SQL injection, XSS attacks, and authentication bypasses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code review:&lt;/strong&gt; Multiple sets of eyes catching potential issues&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Personal Story:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;My pharmacy background naturally led me to emphasize testing in my code. When I built a feature for calculating medication dosages based on patient weight, I didn't just test that it worked with typical values. I tested:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens with zero or negative weight values?&lt;/li&gt;
&lt;li&gt;What happens with extremely high weights (data entry errors)?&lt;/li&gt;
&lt;li&gt;What happens if weight units aren't specified?&lt;/li&gt;
&lt;li&gt;What happens if the calculation produces a dose exceeding maximum limits?&lt;/li&gt;
&lt;li&gt;What happens if database queries fail?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This might seem excessive, but in pharmacy, I learned that edge cases aren't theoretical; they're inevitable. Real users will input invalid data, networks will fail at inopportune moments, and assumptions about "this will never happen" are dangerous.&lt;/p&gt;

&lt;p&gt;My colleagues sometimes joke about my "paranoid" testing approach, but it's caught critical bugs before they reached production. When your professional training emphasizes that mistakes can harm people, you develop a healthy respect for thorough quality assurance.&lt;/p&gt;

&lt;p&gt;This mindset has made me particularly effective in QA roles and has prevented numerous production incidents. I approach code reviews with the same scrutiny I applied to prescription verification: assume nothing, verify everything, and protect the end user.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overcoming Imposter Syndrome
&lt;/h2&gt;

&lt;p&gt;Despite these transferable skills, I still struggled with imposter syndrome during my transition. Scrolling through tech Twitter, I'd see developers who'd been coding since age twelve, had computer science degrees from prestigious universities, and could whiteboard complex algorithms effortlessly. How could I compete?&lt;/p&gt;

&lt;p&gt;The turning point came when I reframed the narrative.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Challenge:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imposter syndrome tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"You're not a &lt;em&gt;real&lt;/em&gt; developer without a CS degree"&lt;/li&gt;
&lt;li&gt;"Everyone else started coding as children; you're so far behind."&lt;/li&gt;
&lt;li&gt;"You're just faking it until someone realizes you don't belong."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These feelings are amplified in tech, where there's a pervasive myth that great programmers are born, not made, and that you need to start young to succeed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Reframe:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's what I eventually realized:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Your healthcare background is a differentiator, not a deficit.&lt;/strong&gt; When I applied for roles at health-tech companies, my pharmacy background wasn't a curiosity; it was a competitive advantage. I understood the problems our users faced because I'd lived them. I could speak clinically with our medical advisory board and technically with our engineering team.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Diversity of thought improves software teams.&lt;/strong&gt; Homogeneous teams produce limited solutions. Teams with varied backgrounds: different industries, different educational paths, different life experiences, build better products. Your perspective matters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;You bring domain expertise that's incredibly valuable.&lt;/strong&gt; There's an explosion of health-tech companies that desperately need people who understand both healthcare and technology. Your dual expertise is rare and valuable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Your problem-solving skills are already advanced.&lt;/strong&gt; You spent years developing systematic thinking, attention to detail, and risk management. These cognitive skills transfer directly to programming. Learning syntax is the easy part.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Practical Strategies:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keep a "wins" journal.&lt;/strong&gt; Document every problem you solve using your transferred skills. When imposter syndrome strikes, review this journal. You'll see concrete evidence of your capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Find community.&lt;/strong&gt; Connect with other career-changers through communities like CodeNewbie, career-change Discord servers, or local meetups. Realizing you're not alone makes a tremendous difference.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Embrace beginner's mind.&lt;/strong&gt; Being new to syntax doesn't mean being new to thinking. I may not have known JavaScript's prototype chain initially, but I understood complex systems, logical reasoning, and methodical troubleshooting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contribute to health-tech.&lt;/strong&gt; Your dual expertise is invaluable in medical software projects. Contributing to open-source health applications or volunteering your skills for health-tech nonprofits reinforces that your background is an asset.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Reframe your narrative.&lt;/strong&gt; Instead of "I'm a pharmacist trying to become a developer," try "I'm a problem-solver expanding my toolkit." Your identity isn't about your title, it's about your capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I still sometimes feel like an imposter. But I've learned that imposter syndrome often signals growth; you're pushing beyond your comfort zone. The key is recognizing that feeling inadequate doesn't mean you &lt;em&gt;are&lt;/em&gt; inadequate. It often means you're learning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Steps to Leverage Your Skills
&lt;/h2&gt;

&lt;p&gt;Understanding that your skills transfer is valuable, but how do you actually leverage them? Here's a concrete roadmap:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Identify Your Strengths
&lt;/h3&gt;

&lt;p&gt;Take fifteen minutes and complete this exercise:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;List five things you excelled at in your healthcare role:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example from my experience:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identifying drug interactions before they cause patient harm&lt;/li&gt;
&lt;li&gt;Explaining complex medical concepts to patients with limited health literacy&lt;/li&gt;
&lt;li&gt;Troubleshooting medication-related problems systematically&lt;/li&gt;
&lt;li&gt;Maintaining meticulous documentation for legal and clinical purposes&lt;/li&gt;
&lt;li&gt;Learning new drugs and clinical guidelines quickly&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Now match each to a programming parallel:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Identifying drug interactions → Debugging code and catching edge cases before production&lt;/li&gt;
&lt;li&gt;Explaining to patients → Writing clear documentation and user-friendly error messages&lt;/li&gt;
&lt;li&gt;Systematic troubleshooting → Methodical debugging and problem-solving approach&lt;/li&gt;
&lt;li&gt;Meticulous documentation → Writing clear code comments, README files, and technical docs&lt;/li&gt;
&lt;li&gt;Learning new drugs quickly → Rapidly learning new frameworks, libraries, and languages&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This exercise isn't just motivational, it's strategic. These become talking points for interviews, content for your portfolio, and focus areas for skill development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Choose Your Learning Path Strategically
&lt;/h3&gt;

&lt;p&gt;Not all learning paths are equal for healthcare professionals. Consider:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Health-tech focused bootcamps or courses:&lt;/strong&gt;&lt;br&gt;
Some bootcamps (like Springboard's Health Tech track) specifically cater to healthcare professionals transitioning to tech. These programs understand your background and help you leverage it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project-based learning:&lt;/strong&gt;&lt;br&gt;
Build projects that combine your interests. When you're learning React, don't build a generic todo app, build a medication tracker. When learning databases, create a drug interaction database. This serves two purposes: you stay motivated by working on relevant problems, and you build a portfolio that showcases your unique expertise.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open-source health software:&lt;/strong&gt;&lt;br&gt;
Contributing to projects like OpenMRS, OpenEMR, or health-tech libraries gives you real-world coding experience while building connections in health-tech communities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Build a Bridge Portfolio
&lt;/h3&gt;

&lt;p&gt;Your portfolio should showcase both skill sets. Instead of generic beginner projects, create applications that demonstrate your domain expertise:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Ideas:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Drug Interaction Checker:&lt;/strong&gt; An application that checks medication combinations for interactions, using public APIs like OpenFDA or RxNorm. Demonstrates API integration, data processing, and healthcare knowledge.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Medication Reminder App:&lt;/strong&gt; Mobile or web app for medication adherence, with features like custom schedules, refill reminders, and interaction warnings. Shows frontend skills, local storage/database management, and understanding of patient needs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Clinical Calculator Collection:&lt;/strong&gt; Web app with common pharmacy calculations (creatinine clearance, ideal body weight, medication dosing adjustments). Demonstrates mathematical logic, input validation, and clinical application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pharmacy Inventory Management System:&lt;/strong&gt; Full-stack application for tracking medication stock, expiration dates, and reorder points. Shows database design, CRUD operations, and real-world business logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Patient Education Content Management:&lt;/strong&gt; Platform for creating, organizing, and sharing medication information sheets. Highlights content management, user authentication, and understanding of healthcare communication needs.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each project should have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean, well-documented code on GitHub&lt;/li&gt;
&lt;li&gt;A deployed demo users can interact with&lt;/li&gt;
&lt;li&gt;A detailed README explaining the clinical problem it solves&lt;/li&gt;
&lt;li&gt;Screenshots or a demo video&lt;/li&gt;
&lt;li&gt;Notes on what you learned technically and how your healthcare background informed design decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Network Strategically
&lt;/h3&gt;

&lt;p&gt;Don't just attend generic tech meetups, focus on health-tech communities:&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Join health-tech LinkedIn groups&lt;/li&gt;
&lt;li&gt;Participate in r/healthIT and r/HealthTech on Reddit&lt;/li&gt;
&lt;li&gt;Follow health-tech companies and their engineering blogs&lt;/li&gt;
&lt;li&gt;Connect with other healthcare professionals who've made the transition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;In-person:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attend health-tech meetups and conferences (HIMSS, Health 2.0)&lt;/li&gt;
&lt;li&gt;Healthcare hackathons (often focused on solving clinical problems)&lt;/li&gt;
&lt;li&gt;Local tech meetups, but emphasize health-tech interests&lt;/li&gt;
&lt;li&gt;Alumni networks from your healthcare program&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt;&lt;br&gt;
Health-tech companies specifically seek candidates with clinical backgrounds. When you network in these spaces, your healthcare experience is an advantage, not something you need to explain or apologize for.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Tell Your Story
&lt;/h3&gt;

&lt;p&gt;Your career transition is a compelling narrative. Use it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update your LinkedIn:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Don't hide your pharmacy background, highlight it&lt;/li&gt;
&lt;li&gt;Frame skills in terms of transferable capabilities: "problem-solving," "systematic analysis," "technical documentation," "risk management"&lt;/li&gt;
&lt;li&gt;Add a summary that explicitly addresses the transition: "Pharmacist transitioning to software development, combining clinical expertise with technical skills to build health-tech solutions"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Write about your journey:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blog posts on Medium or dev.to about lessons learned&lt;/li&gt;
&lt;li&gt;Twitter threads about "Today I learned" moments&lt;/li&gt;
&lt;li&gt;LinkedIn posts about challenges and insights&lt;/li&gt;
&lt;li&gt;Technical tutorials that incorporate healthcare examples&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Prepare your narrative for interviews:&lt;/strong&gt;&lt;br&gt;
Practice explaining your transition concisely and positively:&lt;/p&gt;

&lt;p&gt;"I spent five years in pharmacy, where I developed strong problem-solving skills and a deep understanding of healthcare workflows. I became interested in the technology we used daily and realized I could have more impact by building tools that improve healthcare delivery. I've spent the past year learning full-stack development, focusing on health-tech applications. My clinical background helps me understand user needs and design solutions that actually work in healthcare settings."&lt;/p&gt;

&lt;p&gt;This narrative reframes your transition as purposeful and strategic, not desperate or uncertain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Success Stories
&lt;/h2&gt;

&lt;p&gt;You're not alone in making this transition. Here are three professionals who successfully moved from healthcare to tech:&lt;/p&gt;

&lt;h3&gt;
  
  
  Story 1: Sarah - Pharmacist to Software Engineer
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Background:&lt;/strong&gt; Sarah worked five years in hospital pharmacy before transitioning to software development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skills that transferred most easily:&lt;/strong&gt; "My systematic approach to problem-solving and attention to detail made debugging feel natural. I was already used to double checking everything and thinking through edge cases."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Biggest challenge:&lt;/strong&gt; "Overcoming the feeling that I was 'too late' since I didn't start coding as a teenager. I had to remind myself that my maturity and professional experience were assets."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current role:&lt;/strong&gt; Software engineer at a health-tech startup building clinical decision support tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advice:&lt;/strong&gt; "Don't just learn to code, learn to solve problems with code. Your healthcare background gives you problems worth solving. Build projects that address real clinical needs, and you'll stand out."&lt;/p&gt;

&lt;h3&gt;
  
  
  Story 2: James - Nurse to QA Engineer
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Background:&lt;/strong&gt; James worked six years as an ICU nurse before transitioning to quality assurance engineering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skills that transferred most easily:&lt;/strong&gt; "Nursing taught me to anticipate what could go wrong and implement safeguards. That's exactly what QA is about, thinking through failure scenarios and preventing them."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Biggest challenge:&lt;/strong&gt; "Learning to advocate for quality without coming across as negative. In healthcare, we're trained to speak up about safety concerns, but in tech, I had to learn how to frame issues constructively."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current role:&lt;/strong&gt; QA engineer specializing in medical device software testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advice:&lt;/strong&gt; "Your healthcare safety mindset is valuable, don't lose it when you transition to tech. But learn to communicate in terms of business risk and user impact, not just technical correctness."&lt;/p&gt;

&lt;h3&gt;
  
  
  Story 3: Aisha - Medical Lab Scientist to Data Engineer
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Background:&lt;/strong&gt; Aisha worked four years in clinical laboratory science before moving into data engineering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Skills that transferred most easily:&lt;/strong&gt; "Lab work is all about protocols, documentation, and quality control. Data engineering requires the same rigor—ensuring data quality, documenting processes, and validating results."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Biggest challenge:&lt;/strong&gt; "The pace of change in tech was jarring after working in a highly regulated environment. I had to become comfortable with iteration and accepting that code doesn't need to be perfect before deployment."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current role:&lt;/strong&gt; Data engineer at a clinical research organization, building data pipelines for medical studies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advice:&lt;/strong&gt; "Look for roles that bridge healthcare and tech. Clinical research, health-tech companies, and medical device firms all need people who understand both domains."&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Themes
&lt;/h3&gt;

&lt;p&gt;Across all three stories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Problem-solving skills transferred first and most easily&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The biggest challenges were often mindset shifts, not technical skills&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Their healthcare backgrounds became differentiators in health-tech roles&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;They all wish they'd made the transition sooner&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Addressing Common Concerns
&lt;/h2&gt;

&lt;p&gt;Let's tackle the questions that might be holding you back:&lt;/p&gt;

&lt;h3&gt;
  
  
  "Am I too old?"
&lt;/h3&gt;

&lt;p&gt;No. Full stop.&lt;/p&gt;

&lt;p&gt;Age diversity benefits tech teams by bringing varied perspectives, life experience, and professional maturity. Many successful developers started later in life:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;According to Stack Overflow's 2023 Developer Survey, 40% of developers learned to code after age 25&lt;/li&gt;
&lt;li&gt;Bootcamp graduate data shows students in their 30s and 40s often outperform younger counterparts due to better time management and clearer goals&lt;/li&gt;
&lt;li&gt;Major tech companies increasingly value diverse age ranges—experience with professional environments, communication skills, and project management are assets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your "late start" often means you're more focused, more motivated, and more mature than someone coding fresh out of high school. You understand professional responsibility, workplace dynamics, and career strategy. These are advantages.&lt;/p&gt;

&lt;h3&gt;
  
  
  "Will I have to take a huge pay cut?"
&lt;/h3&gt;

&lt;p&gt;It depends on your path, but it's often temporary:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initial considerations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entry-level developer salaries may be lower than experienced pharmacist salaries initially&lt;/li&gt;
&lt;li&gt;However, tech salary trajectories often outpace healthcare over time&lt;/li&gt;
&lt;li&gt;Remote work opportunities can offset costs (no commute, broader job market)&lt;/li&gt;
&lt;li&gt;Freelancing and consulting in health-tech can command premium rates due to your dual expertise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Long-term potential:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Senior developers often earn significantly more than pharmacists&lt;/li&gt;
&lt;li&gt;Technical leadership roles, specialized positions (like QA automation or technical writing), and health-tech product management can be highly lucrative&lt;/li&gt;
&lt;li&gt;Your healthcare background can command premium rates in health-tech consulting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Strategies to minimize financial impact:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with freelance projects or part-time work while maintaining your current role&lt;/li&gt;
&lt;li&gt;Look for hybrid roles (like pharmacy informatics or clinical systems analyst) that value both backgrounds&lt;/li&gt;
&lt;li&gt;Build skills through evening courses while employed&lt;/li&gt;
&lt;li&gt;Target health-tech companies that value clinical backgrounds and may offer competitive salaries&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  "What about my pharmacy license/degree?"
&lt;/h3&gt;

&lt;p&gt;It's not wasted, it's your differentiator:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your education and license are assets:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Health-tech companies specifically seek clinical expertise&lt;/li&gt;
&lt;li&gt;You can consult on health projects while working as a developer&lt;/li&gt;
&lt;li&gt;Clinical informatics roles require both healthcare and technical knowledge&lt;/li&gt;
&lt;li&gt;You understand regulatory requirements (HIPAA, FDA regulations) that many developers don't&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Maintaining your license:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some states have inactive or non-practicing license status with reduced CE requirements&lt;/li&gt;
&lt;li&gt;You can maintain your license while working in tech&lt;/li&gt;
&lt;li&gt;This keeps doors open for hybrid roles or consulting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Opportunities that value both skills:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pharmacy informatics specialist&lt;/li&gt;
&lt;li&gt;Clinical systems analyst&lt;/li&gt;
&lt;li&gt;Health-tech product manager&lt;/li&gt;
&lt;li&gt;Medical software consultant&lt;/li&gt;
&lt;li&gt;Healthcare data analyst&lt;/li&gt;
&lt;li&gt;Clinical decision support developer&lt;/li&gt;
&lt;li&gt;Digital health entrepreneur&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The rise of clinical informatics, telehealth, and digital therapeutics means demand for professionally trained healthcare workers with technical skills is growing rapidly.&lt;/p&gt;

&lt;h3&gt;
  
  
  "How long will it take?"
&lt;/h3&gt;

&lt;p&gt;Honest answer: It varies, but probably less time than you think:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Different paths:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full-time bootcamp (3-6 months):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intensive, structured learning&lt;/li&gt;
&lt;li&gt;Career services and networking&lt;/li&gt;
&lt;li&gt;Fastest path to job-ready skills&lt;/li&gt;
&lt;li&gt;Best for those who can afford to not work during training&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Part-time bootcamp or courses (6-12 months):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Balance learning with current job&lt;/li&gt;
&lt;li&gt;Less financial risk&lt;/li&gt;
&lt;li&gt;Slower pace but more sustainable&lt;/li&gt;
&lt;li&gt;Common for career changers with responsibilities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Self-taught (6-18 months):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most flexible but requires discipline&lt;/li&gt;
&lt;li&gt;Lower cost but less structure&lt;/li&gt;
&lt;li&gt;Timeline varies significantly based on time commitment&lt;/li&gt;
&lt;li&gt;Works well for self-motivated learners with technical aptitude&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The advantage you have:&lt;/strong&gt;&lt;br&gt;
You're not starting from zero. Your problem-solving skills, attention to detail, and ability to learn complex systems quickly mean you'll likely progress faster than you expect. The learning curve isn't &lt;em&gt;learning to think&lt;/em&gt;, it's &lt;em&gt;learning syntax and tools&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Realistic expectations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3-6 months: Basic competency, can build simple applications&lt;/li&gt;
&lt;li&gt;6-12 months: Job-ready skills, portfolio projects, entry-level positions&lt;/li&gt;
&lt;li&gt;12-18 months: Comfortable with multiple technologies, strong portfolio, competitive for mid-level positions&lt;/li&gt;
&lt;li&gt;18+ months: Specialized skills, potential for senior positions, especially in health-tech niches&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Two years after that frustrating night debugging my first &lt;code&gt;for loop&lt;/code&gt;, I work as a software developer and technical writer. I build applications, write technical documentation, and consult on health-tech projects. But more importantly, I've realized that the skills I developed in pharmacy—the systematic problem-solving, meticulous attention to detail, clear documentation, continuous learning, systems thinking, stakeholder communication, and risk management—weren't left behind. They were the foundation.&lt;/p&gt;

&lt;p&gt;Learning to code didn't mean abandoning my healthcare identity. It meant expanding my toolkit to solve problems in new ways. When I debug complex issues, I use the same methodical approach I used for identifying drug interactions. When I write documentation, I draw on years of explaining medications to patients. When I test code, I apply the same defensive thinking that prevented medication errors.&lt;/p&gt;

&lt;p&gt;You already possess the hard skills: problem-solving, attention to detail, systematic thinking. Learning syntax is the easy part. Your healthcare background isn't baggage; it's your competitive advantage, especially in the rapidly growing health-tech sector.&lt;/p&gt;

&lt;p&gt;If you're a healthcare professional considering this path, remember: you're not starting from scratch. You're building on years of expertise. The question isn't whether you can learn to code, it's what problems you'll solve once you do.&lt;/p&gt;

&lt;h3&gt;
  
  
  Your Action Plan
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;This week:&lt;/strong&gt;&lt;br&gt;
Make a list of three transferable skills you used in your healthcare role this week. Write one sentence for each describing how that skill applies to programming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This month:&lt;/strong&gt;&lt;br&gt;
Complete one beginner coding tutorial. I recommend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;freeCodeCamp's Responsive Web Design Certification&lt;/strong&gt; (free, project-based)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Odin Project's Foundations Course&lt;/strong&gt; (free, comprehensive)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codecademy's Introduction to JavaScript&lt;/strong&gt; (free tier available)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;This quarter:&lt;/strong&gt;&lt;br&gt;
Build one small project that combines your healthcare knowledge with code. It doesn't need to be complex, a simple medication reminder, a dosage calculator, or a drug information lookup tool. The goal is to prove to yourself that you can create something functional.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources to Get Started
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Free Learning Platforms:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;freeCodeCamp (web development)&lt;/li&gt;
&lt;li&gt;The Odin Project (full-stack development)&lt;/li&gt;
&lt;li&gt;Codecademy (multiple languages)&lt;/li&gt;
&lt;li&gt;CS50 (Harvard's intro to computer science)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Health-Tech Communities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Healthcare IT Professionals on LinkedIn&lt;/li&gt;
&lt;li&gt;r/HealthIT and r/healthtech on Reddit&lt;/li&gt;
&lt;li&gt;HIMSS (Healthcare Information and Management Systems Society)&lt;/li&gt;
&lt;li&gt;Health 2.0 Developer Community&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Books for Career Changers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"The Self-Taught Programmer" by Cory Althoff&lt;/li&gt;
&lt;li&gt;"Cracking the Coding Interview" by Gayle Laakmann McDowell&lt;/li&gt;
&lt;li&gt;"The Pragmatic Programmer" by David Thomas and Andrew Hunt&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;CodeNewbie (features career changers)&lt;/li&gt;
&lt;li&gt;Learn to Code With Me&lt;/li&gt;
&lt;li&gt;The Changelog (tech industry insights)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The same brain that calculates pediatric doses can debug complex code. The same attention to detail that catches prescription errors catches software bugs. The same communication skills that counsel patients write clear documentation.&lt;/p&gt;

&lt;p&gt;You're not too old. You're not too late. You're not starting from scratch.&lt;/p&gt;

&lt;p&gt;You're a problem-solver learning a new language.&lt;/p&gt;

&lt;p&gt;And that changes everything.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>careerdevelopment</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Top 10 Test Automation Frameworks for JavaScript Developers (2025 Edition)</title>
      <dc:creator>henry messiah tmt</dc:creator>
      <pubDate>Thu, 30 Oct 2025 13:37:23 +0000</pubDate>
      <link>https://dev.to/henry_messiahtmt_099ca84/top-10-test-automation-frameworks-for-javascript-developers-2025-edition-41fe</link>
      <guid>https://dev.to/henry_messiahtmt_099ca84/top-10-test-automation-frameworks-for-javascript-developers-2025-edition-41fe</guid>
      <description>&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.amazonaws.com%2Fuploads%2Farticles%2F6uoqc5nth0xvsrg3vw6y.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%2F6uoqc5nth0xvsrg3vw6y.png" alt=" " width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JavaScript has evolved from a simple scripting language to the backbone of modern web development. Today's applications are complex, user-facing systems where bugs can cost businesses thousands of dollars and damage user trust. Manual testing alone can't keep pace with rapid deployment cycles and continuous integration demands.&lt;/p&gt;

&lt;p&gt;Test automation solves this challenge by catching regressions early, validating functionality across browsers, and enabling developers to refactor with confidence. But choosing the right testing framework isn't straightforward. Developers face a crowded landscape where each tool promises speed, simplicity, or comprehensive coverage, yet delivers different trade-offs in practice.&lt;/p&gt;

&lt;p&gt;Should you prioritize lightning-fast unit tests? Cross-browser compatibility? A gentle learning curve for your team? The answer depends on your project's unique needs.&lt;/p&gt;

&lt;p&gt;This article breaks down the top 10 JavaScript test automation frameworks for 2025, examining what each does best and where it falls short. Whether you're testing React components, building end-to-end workflows, or validating APIs, you'll find a framework that fits.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes a Great JavaScript Testing Framework?
&lt;/h2&gt;

&lt;p&gt;Before diving into specific tools, let's establish the criteria that separate exceptional frameworks from mediocre ones:&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%2Fz0ej99x86wq4anxpz16t.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%2Fz0ej99x86wq4anxpz16t.png" alt=" " width="731" height="703"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ease of Setup and Use&lt;/strong&gt;: The best frameworks get you writing tests quickly without wrestling with configuration files. Zero-config solutions win points here, though flexibility matters for complex projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type of Testing Supported&lt;/strong&gt;: Different tools excel at different layers. Unit testing frameworks validate individual functions, integration tests verify how modules work together, and end-to-end (E2E) frameworks simulate real user interactions across entire applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ecosystem and Community Support&lt;/strong&gt;: Popular frameworks benefit from extensive documentation, active maintainers, and rich plugin ecosystems. When you hit a roadblock, community support can make or break your experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CI/CD Integration&lt;/strong&gt;: Modern development demands seamless integration with Jenkins, GitHub Actions, GitLab CI, and other automation platforms. Look for frameworks with built-in reporters and parallel execution support.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Browser and Device Coverage&lt;/strong&gt;: If you're testing web UIs, cross-browser compatibility is non-negotiable. The best E2E frameworks handle Chrome, Firefox, Safari, and Edge without manual driver management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reporting and Debugging Tools&lt;/strong&gt;: Clear error messages, visual diffs, and actionable stack traces accelerate debugging. Time-travel debugging and automatic screenshots raise the bar even higher.&lt;/p&gt;

&lt;p&gt;With these benchmarks in mind, let's explore the frameworks that dominate JavaScript testing in 2025.&lt;/p&gt;

&lt;h2&gt;
  
  
  Top 10 Test Automation Frameworks for JavaScript Developers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  (A) Jest
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;: Jest is Facebook's testing framework designed for simplicity and speed. It's the default choice for React applications but works equally well with Vue, Angular, and Node.js backends.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero configuration for most JavaScript projects&lt;/li&gt;
&lt;li&gt;Built-in code coverage reports with no additional setup&lt;/li&gt;
&lt;li&gt;Snapshot testing for UI components and data structures&lt;/li&gt;
&lt;li&gt;Powerful mocking capabilities for dependencies and modules&lt;/li&gt;
&lt;li&gt;Parallel test execution for faster feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Case&lt;/strong&gt;: Jest shines in component-driven development. If you're building a React app or need quick unit tests with minimal setup, Jest delivers exceptional developer experience out of the box.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; jest
npx jest &lt;span class="nt"&gt;--init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example test file (sum.test.js)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// sum.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// sum.test.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./sum&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sum function&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;adds 1 + 2 to equal 3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&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="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;adds negative numbers correctly&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Extremely beginner-friendly&lt;/li&gt;
&lt;li&gt;Excellent documentation and a massive community&lt;/li&gt;
&lt;li&gt;Fast watch mode for test-driven development&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Not designed for E2E browser testing&lt;/li&gt;
&lt;li&gt;Snapshot tests can become brittle if overused&lt;/li&gt;
&lt;li&gt;Less flexible than Mocha for custom configurations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  (B) Mocha + Chai
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;: Mocha is a veteran testing framework known for flexibility. Paired with Chai (an assertion library), it forms a powerful, customizable testing stack popular in backend development.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Highly flexible: use any assertion library, spy library, or mocking tool&lt;/li&gt;
&lt;li&gt;Supports multiple interfaces (BDD, TDD, exports)&lt;/li&gt;
&lt;li&gt;Runs in both Node.js and browsers&lt;/li&gt;
&lt;li&gt;Extensive plugin ecosystem&lt;/li&gt;
&lt;li&gt;Asynchronous testing with promises, callbacks, or async/await&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Case&lt;/strong&gt;: Choose Mocha when you need full control over your testing stack. It's perfect for Node.js APIs, microservices, and teams with specific tooling requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; mocha chai
npx mocha
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example test file (test/api.test.js)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chai&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;chai&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;expect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;chai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Array operations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should return -1 when value is not present&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should handle async operations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Maximum flexibility and customization&lt;/li&gt;
&lt;li&gt;Mature ecosystem with years of battle-testing&lt;/li&gt;
&lt;li&gt;Works seamlessly with TypeScript&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Requires manual setup of assertions and other utilities&lt;/li&gt;
&lt;li&gt;Steeper learning curve than opinionated frameworks&lt;/li&gt;
&lt;li&gt;No built-in mocking or code coverage&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  (C) Jasmine
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;: Jasmine is a behavior-driven development (BDD) framework that requires zero external dependencies. Its straightforward syntax makes it accessible to developers new to testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero dependencies—everything included out of the box&lt;/li&gt;
&lt;li&gt;Clean, readable BDD syntax&lt;/li&gt;
&lt;li&gt;Built-in assertions, spies, and mocks&lt;/li&gt;
&lt;li&gt;Can run in Node.js or browser environments&lt;/li&gt;
&lt;li&gt;Standalone test runner included&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Case&lt;/strong&gt;: Jasmine fits projects where simplicity and low overhead matter more than bleeding-edge features. It's ideal for small to medium applications and teams learning test automation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; jasmine
npx jasmine init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example test file (spec/calculator.spec.js)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Calculator&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;beforeEach&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;calculator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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;a&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should add two numbers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;calculator&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="mi"&gt;5&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="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should multiply two numbers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;No configuration needed&lt;/li&gt;
&lt;li&gt;Easy for beginners to understand&lt;/li&gt;
&lt;li&gt;Stable and mature&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Slower than modern alternatives like Vitest&lt;/li&gt;
&lt;li&gt;Smaller community compared to Jest&lt;/li&gt;
&lt;li&gt;Limited built-in tools for complex scenarios&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  (D) Cypress
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;: Cypress revolutionized E2E testing with its developer-first approach. It runs directly in the browser, providing real-time reloads, automatic waiting, and powerful debugging tools.&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%2Fp1hv5j4v3nj09cgrxk83.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%2Fp1hv5j4v3nj09cgrxk83.png" alt=" " width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time-travel debugging with snapshots at every step&lt;/li&gt;
&lt;li&gt;Automatic waiting eliminates flaky tests from timing issues&lt;/li&gt;
&lt;li&gt;Real-time test reloading during development&lt;/li&gt;
&lt;li&gt;Network traffic control and API mocking&lt;/li&gt;
&lt;li&gt;Screenshots and videos on test failures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Case&lt;/strong&gt;: Cypress is the gold standard for web application E2E testing. Use it when you need reliable, maintainable tests for critical user workflows like authentication, checkout processes, or form submissions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; cypress
npx cypress open
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example test file (cypress/e2e/login.cy.js)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Login Flow&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;beforeEach&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;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;visit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should login successfully with valid credentials&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cy&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;[data-testid="email"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;cy&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;[data-testid="password"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;cy&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;[data-testid="submit-btn"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;include&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;/dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Welcome back&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should show error with invalid credentials&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cy&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;[data-testid="email"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wrong@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;cy&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;[data-testid="password"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wrongpass&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;cy&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;[data-testid="submit-btn"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nx"&gt;cy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid credentials&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;should&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;be.visible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Outstanding developer experience&lt;/li&gt;
&lt;li&gt;Excellent documentation and community&lt;/li&gt;
&lt;li&gt;Intuitive API for writing readable tests&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Limited to Chromium-based browsers by default (Firefox support in beta)&lt;/li&gt;
&lt;li&gt;Can't test multiple tabs or origins easily&lt;/li&gt;
&lt;li&gt;Slower execution compared to Playwright for large suites&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  (E) Playwright
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;: Microsoft's Playwright is a next-generation browser automation framework supporting Chromium, Firefox, and WebKit. It's built for modern web apps requiring cross-browser coverage and parallel execution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;True cross-browser testing with a single API&lt;/li&gt;
&lt;li&gt;Auto-waiting for elements to be ready&lt;/li&gt;
&lt;li&gt;Parallel test execution across multiple browsers&lt;/li&gt;
&lt;li&gt;Network interception and mocking&lt;/li&gt;
&lt;li&gt;Mobile device emulation with touch and geolocation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Case&lt;/strong&gt;: When cross-browser compatibility is critical and you need speed, Playwright delivers. It's perfect for enterprise applications, Progressive Web Apps (PWAs), and mobile-responsive testing.&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%2Fuwgtmujw6hycfhilgzgd.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%2Fuwgtmujw6hycfhilgzgd.png" alt=" " width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; @playwright/test
npx playwright &lt;span class="nb"&gt;install
&lt;/span&gt;npx playwright &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example test file (tests/example.spec.js)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@playwright/test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;basic navigation test&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;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/Example Domain/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;form submission test&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;page&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/contact&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;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&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;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&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="s1"&gt;john@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;selectOption&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#country&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;US&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;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button[type="submit"]&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;locator&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-message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBeVisible&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Fastest E2E framework for large test suites&lt;/li&gt;
&lt;li&gt;Excellent browser coverage, including WebKit&lt;/li&gt;
&lt;li&gt;Powerful auto-wait mechanism reduces flakiness&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Steeper learning curve than Cypress&lt;/li&gt;
&lt;li&gt;Less polished developer tools (though improving rapidly)&lt;/li&gt;
&lt;li&gt;Smaller community and fewer third-party plugins&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  (F) Puppeteer
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;: Puppeteer is Google's Node.js library for controlling headless Chrome. While not a full testing framework, it excels at browser automation, scraping, and UI regression testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Direct control over Chrome DevTools Protocol&lt;/li&gt;
&lt;li&gt;Generate screenshots and PDFs programmatically&lt;/li&gt;
&lt;li&gt;Automate form submissions and keyboard input&lt;/li&gt;
&lt;li&gt;Intercept network requests&lt;/li&gt;
&lt;li&gt;Integrates with Jest or Mocha for assertions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Case&lt;/strong&gt;: Puppeteer fits niche scenarios like generating PDF reports, testing Chrome extensions, or automating tasks that don't require full framework features.&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%2Fksl5za9pdk3nrxc0mdoi.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%2Fksl5za9pdk3nrxc0mdoi.png" alt=" " width="800" height="590"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example test file (test/screenshot.js)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;puppeteer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;puppeteer&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;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;browser&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;puppeteer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&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;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newPage&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;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Take screenshot&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;screenshot&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;example.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Generate PDF&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pdf&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;page.pdf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// Test interactions&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a[href="/about"]&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;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitForSelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1&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;title&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;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;$eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Page title:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Lightweight and fast&lt;/li&gt;
&lt;li&gt;Great for web scraping and automation&lt;/li&gt;
&lt;li&gt;Excellent Chrome/Chromium integration&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Chrome-only (no Firefox or Safari)&lt;/li&gt;
&lt;li&gt;Requires pairing with testing frameworks for assertions&lt;/li&gt;
&lt;li&gt;Not designed for comprehensive E2E suites&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  (G) WebdriverIO
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;: WebdriverIO is a full-featured test automation framework supporting web, mobile (React Native, Appium), and desktop applications. It's built on the WebDriver protocol with modern async/await syntax.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Supports web, iOS, and Android testing&lt;/li&gt;
&lt;li&gt;Built-in test runner with parallel execution&lt;/li&gt;
&lt;li&gt;Smart element selectors with automatic retries&lt;/li&gt;
&lt;li&gt;Extensive plugin ecosystem&lt;/li&gt;
&lt;li&gt;Integrates with Selenium Grid and cloud services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Case&lt;/strong&gt;: WebdriverIO is ideal for teams needing comprehensive test coverage across platforms. If you're testing web and mobile apps with a unified framework, this is your best bet.&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%2Fc82lodjtbgwqp5n7e87f.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%2Fc82lodjtbgwqp5n7e87f.png" alt=" " width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; @wdio/cli
npx wdio config
npx wdio run wdio.conf.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example test file (test/specs/example.e2e.js)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WebdriverIO example&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should verify page title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toHaveTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Example Domain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;should interact with elements&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com/search&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;searchInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#search&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;searchInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WebdriverIO&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;submitBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button[type="submit"]&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;submitBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.results&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="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;results&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBeDisplayed&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Unmatched platform coverage&lt;/li&gt;
&lt;li&gt;Mature and actively maintained&lt;/li&gt;
&lt;li&gt;Strong Sauce Labs and BrowserStack integration&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Complex setup for beginners&lt;/li&gt;
&lt;li&gt;Heavier than modern alternatives&lt;/li&gt;
&lt;li&gt;Configuration can be overwhelming&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  (H) TestCafe
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;: TestCafe is a Node.js E2E testing tool that doesn't require WebDriver or browser plugins. It injects scripts directly into pages, making setup remarkably simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Zero browser plugin or WebDriver setup&lt;/li&gt;
&lt;li&gt;Concurrent test execution&lt;/li&gt;
&lt;li&gt;Automatic waiting for elements&lt;/li&gt;
&lt;li&gt;Built-in support for CI/CD systems&lt;/li&gt;
&lt;li&gt;Live mode for debugging tests in real-time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Case&lt;/strong&gt;: TestCafe suits teams wanting E2E testing without infrastructure complexity. It's great for startups and small teams prioritizing quick wins over advanced features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; testcafe
npx testcafe chrome tests/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example test file (tests/basic.test.js)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Selector&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;testcafe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;fixture&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Getting Started&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;page&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Basic navigation&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="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Selector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;eql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Example Domain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Selector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;withText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;More information&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Selector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Form interaction&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="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;typeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&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="s1"&gt;testuser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;typeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#password&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;password123&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#submit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Selector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.welcome-message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Easiest E2E framework to set up&lt;/li&gt;
&lt;li&gt;No external dependencies&lt;/li&gt;
&lt;li&gt;Cross-browser support out of the box&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Slower than Playwright and Cypress&lt;/li&gt;
&lt;li&gt;Smaller ecosystem and community&lt;/li&gt;
&lt;li&gt;Debugging tools are less sophisticated than competitors&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  (I) Vitest
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;: Vitest is the newest entrant, designed specifically for Vite-powered applications. It's blazingly fast and shares configuration with Vite, eliminating setup friction.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lightning-fast execution with native ESM support&lt;/li&gt;
&lt;li&gt;Compatible with Jest API (easy migration)&lt;/li&gt;
&lt;li&gt;Hot Module Replacement (HMR) for instant feedback&lt;/li&gt;
&lt;li&gt;Built-in TypeScript support&lt;/li&gt;
&lt;li&gt;Component testing for Vue, React, and Svelte&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Case&lt;/strong&gt;: If you're building with Vite, Vitest is a no-brainer. It's also excellent for projects prioritizing speed and modern JavaScript features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example test file (src/utils.test.js)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vitest&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;formatCurrency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&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="s2"&gt;`$&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;formatCurrency&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;formats numbers with two decimals&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;formatCurrency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$10.00&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;formatCurrency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;10.5&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$10.50&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rounds to two decimal places&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;formatCurrency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;10.126&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$10.13&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Async testing&lt;/span&gt;
&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;API utilities&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fetches user data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fetchUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&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;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetchUser&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="nf"&gt;expect&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="nf"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Fastest unit testing framework available&lt;/li&gt;
&lt;li&gt;Seamless Vite integration&lt;/li&gt;
&lt;li&gt;Modern, future-proof architecture&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Still maturing (less stable than Jest)&lt;/li&gt;
&lt;li&gt;Smaller community and fewer resources&lt;/li&gt;
&lt;li&gt;Not suitable for E2E testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  (J) Nightwatch.js
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;: Nightwatch is an all-in-one E2E testing solution with built-in support for Selenium WebDriver and Appium. It emphasizes simplicity with a clean, readable syntax.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Built-in test runner and assertion library&lt;/li&gt;
&lt;li&gt;Page Object Model support out of the box&lt;/li&gt;
&lt;li&gt;Native mobile testing via Appium&lt;/li&gt;
&lt;li&gt;Parallel execution with workers&lt;/li&gt;
&lt;li&gt;Cloud testing service integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ideal Use Case&lt;/strong&gt;: Nightwatch fits teams already invested in Selenium infrastructure or needing mobile testing without adding tools like WebdriverIO.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting Started&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example test file (tests/github.js)&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GitHub Test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;browser&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://github.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitForElementVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&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;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;titleContains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;GitHub&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;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input[name="q"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input[name="q"]&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;nightwatch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button[type="submit"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pause&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;containsText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.repo-list&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;nightwatch&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&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;Navigation Test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;browser&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://nightwatchjs.org&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitForElementVisible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.hero&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a[href="/guide"]&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;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlContains&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/guide&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;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;visible&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Complete solution requiring minimal plugins&lt;/li&gt;
&lt;li&gt;Good documentation and examples&lt;/li&gt;
&lt;li&gt;Active development and updates&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Slower than Playwright/Cypress&lt;/li&gt;
&lt;li&gt;Smaller community than leading frameworks&lt;/li&gt;
&lt;li&gt;Less intuitive API compared to modern alternatives&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparison Table: Choosing the Right Framework
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Speed&lt;/th&gt;
&lt;th&gt;Learning Curve&lt;/th&gt;
&lt;th&gt;Ideal For&lt;/th&gt;
&lt;th&gt;CI/CD Ready&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Jest&lt;/td&gt;
&lt;td&gt;Unit&lt;/td&gt;
&lt;td&gt;⚡⚡⚡⚡&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;td&gt;React apps&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mocha + Chai&lt;/td&gt;
&lt;td&gt;Unit&lt;/td&gt;
&lt;td&gt;⚡⚡⚡&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Backend testing&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jasmine&lt;/td&gt;
&lt;td&gt;Unit&lt;/td&gt;
&lt;td&gt;⚡⚡⚡&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;td&gt;Beginners&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cypress&lt;/td&gt;
&lt;td&gt;E2E&lt;/td&gt;
&lt;td&gt;⚡⚡⚡⚡&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Web UI testing&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Playwright&lt;/td&gt;
&lt;td&gt;E2E&lt;/td&gt;
&lt;td&gt;⚡⚡⚡⚡⚡&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Cross-browser tests&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Puppeteer&lt;/td&gt;
&lt;td&gt;Automation&lt;/td&gt;
&lt;td&gt;⚡⚡⚡⚡&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Chrome automation&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebdriverIO&lt;/td&gt;
&lt;td&gt;E2E/Mobile&lt;/td&gt;
&lt;td&gt;⚡⚡⚡&lt;/td&gt;
&lt;td&gt;Difficult&lt;/td&gt;
&lt;td&gt;Full-stack teams&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TestCafe&lt;/td&gt;
&lt;td&gt;E2E&lt;/td&gt;
&lt;td&gt;⚡⚡⚡&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;td&gt;Simple E2E needs&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vitest&lt;/td&gt;
&lt;td&gt;Unit&lt;/td&gt;
&lt;td&gt;⚡⚡⚡⚡⚡&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;td&gt;Vite projects&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nightwatch.js&lt;/td&gt;
&lt;td&gt;E2E&lt;/td&gt;
&lt;td&gt;⚡⚡⚡&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;td&gt;Selenium users&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Best Frameworks by Use Case
&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%2Fyhsom5kfknwsiuyvaany.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%2Fyhsom5kfknwsiuyvaany.png" alt=" " width="730" height="731"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fastest for Unit Testing&lt;/strong&gt;: Vitest takes the crown with its native ESM support and Vite integration. Jest remains a close second with excellent caching mechanisms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for Cross-Browser E2E Testing&lt;/strong&gt;: Playwright leads with comprehensive browser support and parallel execution. TestCafe offers a simpler alternative for teams avoiding complex setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for Full-Stack Teams&lt;/strong&gt;: WebdriverIO provides unified testing across web, iOS, and Android platforms. Combine it with Jest for complete coverage from unit to E2E.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Beginner-Friendly Options&lt;/strong&gt;: Jest and Cypress offer the smoothest onboarding experiences. Jasmine is great for those learning testing fundamentals without framework complexity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Most Scalable for CI/CD&lt;/strong&gt;: Playwright and Cypress both integrate seamlessly with modern CI/CD pipelines, offering parallelization, retries, and detailed reporting out of the box.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Pick the Right Framework for Your Project
&lt;/h2&gt;

&lt;p&gt;Choosing wisely requires matching frameworks to your specific context:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Define Your Testing Needs&lt;/strong&gt;&lt;br&gt;
Start by categorizing what you need to test. Are you validating individual functions (unit tests), checking how modules integrate (integration tests), or simulating user journeys (E2E tests)? Most projects need multiple layers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Check Project Stack Compatibility&lt;/strong&gt;&lt;br&gt;
If you're using React with Vite, Vitest is the natural choice for unit tests. Angular projects often pair well with Jasmine or Jest. For frameworks like Next.js or Nuxt, Jest handles server and client testing elegantly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Evaluate CI/CD Integration&lt;/strong&gt;&lt;br&gt;
Review your deployment pipeline. GitHub Actions, GitLab CI, and Jenkins all have excellent support for major frameworks. Playwright and Cypress offer official Docker images and parallel execution strategies that scale with your needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Consider Team Experience&lt;/strong&gt;&lt;br&gt;
New to testing? Jest and Cypress provide the gentlest learning curves with extensive tutorials. Experienced teams might prefer Mocha's flexibility or Playwright's power features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Assess Documentation Quality&lt;/strong&gt;&lt;br&gt;
Poor documentation kills productivity. Check official docs, community tutorials, and Stack Overflow activity. Jest, Cypress, and Playwright all excel here with comprehensive guides and active communities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Test automation isn't optional in modern JavaScript development—it's the foundation of sustainable, high-quality software. The frameworks covered here represent the best tools available in 2025, each solving distinct problems.&lt;/p&gt;

&lt;p&gt;For most teams, a combination approach works best: Jest or Vitest for fast unit tests, plus Cypress or Playwright for critical E2E workflows. This layered strategy catches bugs early while validating real user experiences.&lt;/p&gt;

&lt;p&gt;Don't get paralyzed by choice. Pick one framework aligned with your immediate needs and start writing tests today. You can always add complementary tools as your project grows. The key is building the testing habit; the specific framework matters less than consistent coverage.&lt;/p&gt;

&lt;p&gt;Experiment with a couple of options from this list. Set up a small proof-of-concept, run a few tests, and decide which tool fits your workflow. The best framework is the one your team will actually use.&lt;/p&gt;

&lt;p&gt;Start small, test often, and let automation amplify your team's ability to ship confidently.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>devops</category>
    </item>
    <item>
      <title>Designing Accessible Dark Mode Interfaces: A Step-by-Step Guide for Modern Web Designers</title>
      <dc:creator>henry messiah tmt</dc:creator>
      <pubDate>Wed, 29 Oct 2025 20:01:14 +0000</pubDate>
      <link>https://dev.to/henry_messiahtmt_099ca84/designing-accessible-dark-mode-interfaces-a-step-by-step-guide-for-modern-web-designers-45ao</link>
      <guid>https://dev.to/henry_messiahtmt_099ca84/designing-accessible-dark-mode-interfaces-a-step-by-step-guide-for-modern-web-designers-45ao</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Dark mode is everywhere, from mobile apps to developer tools and websites. It’s sleek, power-efficient, and easier on the eyes for many users.&lt;/p&gt;

&lt;p&gt;But there’s a catch: most dark mode designs aren’t accessible. Poor contrast, harsh text, and invisible icons make them difficult to use for people with visual impairments, and tiring for everyone else.&lt;/p&gt;

&lt;p&gt;In this guide, you’ll build your own accessible dark mode layout from scratch, learning best practices as you go. By the end, you’ll know how to design, test, and implement dark mode that’s both stylish and inclusive. You will be able to build interchangable theme as seen bellow:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fshaw8hmlm1f52ai471f5.gif" 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%2Fshaw8hmlm1f52ai471f5.gif" alt="ScreenRecording2025-10-28121345-ezgif.com-optimize" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you begin, ensure you meet a few basic requirements to follow this guide smoothly. These will help you understand each step and build your own accessible dark mode interface without issues.&lt;/p&gt;

&lt;p&gt;You’ll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Basic web development knowledge:&lt;/strong&gt; comfortable with HTML, CSS, and a bit of JavaScript.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A code editor:&lt;/strong&gt; such as Visual Studio Code, Sublime Text, or Atom.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A modern browser:&lt;/strong&gt; Chrome, Firefox, or Edge for previewing and testing your design.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basic understanding of accessibility principles:&lt;/strong&gt; like color contrast and readability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optional but helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Familiarity with design tools such as Figma or Adobe XD (for visual testing).&lt;/li&gt;
&lt;li&gt;Access to accessibility tools like Stark or WebAIM Contrast Checker.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re missing any of these, take a moment to set them up first, so that we can flow together effortlessly.&lt;br&gt;
Once these prerequisites are in place, you’re ready to start building your own inclusive dark mode layout from scratch.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting Up Your Project
&lt;/h2&gt;

&lt;p&gt;With your tools ready, it’s time to create your workspace. In this step, you’ll build the structure that will hold your dark mode interface.&lt;/p&gt;

&lt;p&gt;Let’s start by creating a simple &lt;code&gt;HTML&lt;/code&gt; + &lt;code&gt;CSS&lt;/code&gt; + &lt;code&gt;JavaScript&lt;/code&gt; project that you’ll use throughout this tutorial.&lt;/p&gt;
&lt;h3&gt;
  
  
  Create Your Project Folder
&lt;/h3&gt;

&lt;p&gt;On your computer, create a new folder called dark-mode-tutorial.&lt;/p&gt;

&lt;p&gt;If you’re using Windows, right-click on your desktop → New → Folder → name it dark-mode-tutorial.&lt;/p&gt;

&lt;p&gt;Alternatively, open your terminal or command prompt and run:&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;mkdir&lt;/span&gt; &lt;span class="nx"&gt;dark&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;tutorial&lt;/span&gt;
&lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="nx"&gt;dark&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;tutorial&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the folder in your code editor (for example, Visual Studio Code).&lt;/p&gt;

&lt;p&gt;In VS Code, go to File → Open Folder → dark-mode-tutorial. Or from your terminal, run:&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;code&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This opens the current folder directly in VS Code. Now, you’re inside your project, the creative canvas where everything will unfold.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Three Files
&lt;/h3&gt;

&lt;p&gt;Inside your dark-mode-tutorial folder, create these three files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;dark&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;mode&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;tutorial&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;css&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can do this by:&lt;br&gt;
Right-clicking in VS Code’s file explorer → New File, or Running these commands in your terminal:&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;touch&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;css&lt;/span&gt; &lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This trio forms the backbone of your dark mode project: &lt;code&gt;HTML&lt;/code&gt; for structure, &lt;code&gt;CSS&lt;/code&gt; for design, and &lt;code&gt;JavaScript&lt;/code&gt; for interactivity.&lt;/p&gt;

&lt;p&gt;Before we &lt;code&gt;style&lt;/code&gt; and &lt;code&gt;script&lt;/code&gt;, let’s fill your &lt;code&gt;HTML&lt;/code&gt; file with a clean, accessible layout.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add the Starter &lt;code&gt;HTML&lt;/code&gt; Code
&lt;/h3&gt;

&lt;p&gt;Every great interface begins with solid structure. Let’s add your starter &lt;code&gt;HTML&lt;/code&gt; code that is simple, semantic, and screen-reader friendly.&lt;/p&gt;

&lt;p&gt;Now, open the &lt;code&gt;index.html&lt;/code&gt; file in your editor.&lt;br&gt;
To do that:&lt;br&gt;
In VS Code, click &lt;code&gt;index.html&lt;/code&gt; in the left panel. Paste in the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="nx"&gt;DOCTYPE&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UTF-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viewport&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;width=device-width, initial-scale=1.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Accessible&lt;/span&gt; &lt;span class="nx"&gt;Dark&lt;/span&gt; &lt;span class="nx"&gt;Mode&lt;/span&gt; &lt;span class="nx"&gt;Demo&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/title&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stylesheet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;style.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/head&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Accessible&lt;/span&gt; &lt;span class="nx"&gt;Dark&lt;/span&gt; &lt;span class="nx"&gt;Mode&lt;/span&gt; &lt;span class="nx"&gt;Demo&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;theme-toggle&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Toggle&lt;/span&gt; &lt;span class="nx"&gt;Theme&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;section&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h2&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;This&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="nx"&gt;demonstrates&lt;/span&gt; &lt;span class="nx"&gt;how&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;build&lt;/span&gt; &lt;span class="nx"&gt;an&lt;/span&gt; &lt;span class="nx"&gt;accessible&lt;/span&gt; &lt;span class="nx"&gt;dark&lt;/span&gt; &lt;span class="nx"&gt;mode&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/section&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/main&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;script.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/body&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/html&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save your file (Ctrl + S or Cmd + S).&lt;br&gt;
Now that your basic structure is ready, let’s make it both beautiful and accessible.&lt;/p&gt;
&lt;h2&gt;
  
  
  Understanding Accessibility in Dark Mode
&lt;/h2&gt;

&lt;p&gt;Now that your structure is set, let’s talk about why accessibility matters in dark mode.&lt;br&gt;
Even the most elegant design fails if users can’t comfortably read or interact with it.&lt;/p&gt;

&lt;p&gt;Accessibility ensures inclusivity and dark mode introduces unique visual challenges that we must address.&lt;/p&gt;

&lt;p&gt;Accessibility means designing for everyone, including users with low vision or color blindness. In dark mode, even small mistakes in color contrast can make text unreadable.&lt;/p&gt;
&lt;h3&gt;
  
  
  Apply a Comfortable Dark Background
&lt;/h3&gt;

&lt;p&gt;Open your &lt;code&gt;style.css&lt;/code&gt; file:&lt;br&gt;
In VS Code, click on &lt;code&gt;style.css&lt;/code&gt; in the left sidebar. Then paste in the following &lt;code&gt;CSS&lt;/code&gt;code:&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;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;121212&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* softer than pure black */&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;E0E0E0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* light gray text */&lt;/span&gt;
  &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Helvetica&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sans&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;1.6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nx"&gt;rem&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;Why not use pure black (#000000)?&lt;br&gt;
Because white text on a pure black background causes glare, especially for users with astigmatism or light sensitivity (I am a pharmacist, you can believe me on this).&lt;br&gt;
A dark gray background is easier on the eyes and improves readability.&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%2Fv7tc4wly5zuuyd6611gu.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%2Fv7tc4wly5zuuyd6611gu.png" alt="Screenshot 2025-10-27 162903" width="746" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you’ve created a comfortable visual base, let’s refine your color palette for clarity and balance.&lt;/p&gt;
&lt;h2&gt;
  
  
  Choosing the Right Color Palette
&lt;/h2&gt;

&lt;p&gt;Colors define how users perceive your interface, so good color contrast makes dark mode usable.&lt;/p&gt;

&lt;p&gt;A good dark mode color palette is calm, readable, and adheres to WCAG 2.1 contrast standards (at least 4.5:1 for normal text).&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%2Fdloif9pfan96snzll255.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%2Fdloif9pfan96snzll255.png" alt="Screenshot 2025-10-27 163158" width="740" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let us now bring the colors to life in our next step. &lt;/p&gt;
&lt;h3&gt;
  
  
  Add Color Variables
&lt;/h3&gt;

&lt;p&gt;Now that we understand what a good dark mode color palette is, let’s define reusable color variables in your CSS for consistency.&lt;/p&gt;

&lt;p&gt;Still in your &lt;code&gt;style.css&lt;/code&gt; file, scroll to the top and add these color variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--background-dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#121212&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--text-light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#E0E0E0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--accent-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#BB86FC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* soft purple */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--background-dark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--text-light&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--accent-color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.6rem&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bold&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;Tip: Use tools like Contrast Checker by WebAIM&lt;br&gt;
 to test your color combinations.&lt;/p&gt;

&lt;p&gt;## Typography and Readability&lt;br&gt;
Typography is where accessibility meets design.&lt;br&gt;
Readable type keeps users engaged and reduces visual fatigue, especially in dark mode.&lt;/p&gt;

&lt;p&gt;Readable typography is essential in dark mode.&lt;br&gt;
Text should be slightly larger, well-spaced, and never pure white.&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%2Fx2umh6vjcida5wwiyjrr.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%2Fx2umh6vjcida5wwiyjrr.png" alt="Screenshot 2025-10-27 164449" width="735" height="539"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update Your style.css File&lt;/strong&gt;&lt;br&gt;
Scroll down and add these new styles:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;h2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;p&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#E0E0E0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c"&gt;/* not pure white */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;main&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;700px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt; &lt;span class="nb"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Avoid ultra-thin fonts. They can fade or disappear against dark backgrounds. Stick to medium or bold weights for headings.&lt;/p&gt;

&lt;p&gt;Now that your text is legible, it’s time to enhance your visual elements like icons and images.&lt;/p&gt;

&lt;h2&gt;
  
  
  Icons, Illustrations, and Imagery
&lt;/h2&gt;

&lt;p&gt;Dark mode affects visuals too. Bright icons or images that look great in light mode may disappear in dark mode. &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%2Fka6zjbtpcg0sdr89rghq.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%2Fka6zjbtpcg0sdr89rghq.png" alt="Screenshot 2025-10-27 165038" width="749" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Add an Image
&lt;/h3&gt;

&lt;p&gt;In your &lt;code&gt;index.html&lt;/code&gt;, go to the  section and add this line under the &lt;/p&gt;
&lt;p&gt; tag:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light-logo.png&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Company logo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;logo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  Adjust the Image in CSS
&lt;/h3&gt;

&lt;p&gt;Visuals add personality, but they can break dark mode if not optimized.&lt;br&gt;
Icons may fade, and bright images can overpower the background.&lt;br&gt;
To prevent this, balance brightness and contrast:&lt;br&gt;
Open your&lt;code&gt;style.css&lt;/code&gt; again and add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;brightness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;contrast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&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;p&gt;For the best results, prepare two logo versions, one for light mode and one for dark mode, and switch them dynamically in JavaScript (we’ll cover that next).&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding a Dark Mode Toggle (with JavaScript)
&lt;/h2&gt;

&lt;p&gt;Let’s make your design interactive by allowing users to toggle between light and dark themes. We are empowering users to switch between light and dark modes with a simple button.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add a Data Attribute
&lt;/h3&gt;

&lt;p&gt;In your &lt;code&gt;index.html&lt;/code&gt;, locate the &lt;code&gt;&amp;lt;body&amp;gt;&lt;/code&gt; tag and modify it like this:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;theme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;h3&gt;
  
  
  Add JavaScript to Toggle Themes
&lt;/h3&gt;

&lt;p&gt;Now, open your &lt;code&gt;script.js&lt;/code&gt; file (click on it in your editor) and paste this code:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toggleBtn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;theme-toggle&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;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;toggleBtn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-theme&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;newTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentTheme&lt;/span&gt; &lt;span class="o"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;light&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;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;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;data-theme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newTheme&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;h3&gt;
  
  
  Define Light and Dark Themes in CSS
&lt;/h3&gt;

&lt;p&gt;Back in your style.css, scroll to the bottom and add:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-theme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"light"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--background-dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#FFFFFF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--text-light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#111111&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--accent-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#6200EE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;data-theme&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"dark"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--background-dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#121212&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--text-light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#E0E0E0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--accent-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#BB86FC&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;p&gt;Test it:&lt;/p&gt;

&lt;p&gt;Save all files (Ctrl + S or Cmd + S).&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;index.html&lt;/code&gt; in your browser (double-click the file or run open &lt;code&gt;index.html).&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Click the Toggle Theme button, your dark mode should now switch dynamically like you see bellow. &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%2Fshaw8hmlm1f52ai471f5.gif" 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%2Fshaw8hmlm1f52ai471f5.gif" alt="ScreenRecording2025-10-28121345-ezgif.com-optimize" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing Accessibility
&lt;/h2&gt;

&lt;p&gt;Never assume your design is accessible, always test it. Accessibility testing ensures your dark mode works for everyone, including users with visual impairments or those viewing your site under different lighting conditions.&lt;/p&gt;

&lt;p&gt;Start by opening your project in a browser. Locate your &lt;code&gt;index.html&lt;/code&gt; file inside the dark-mode-tutorial folder and double-click it to open. You can also right-click and choose Open With → Chrome, Firefox, or Edge. Try toggling between light and dark themes using the “Toggle Theme” button.&lt;/p&gt;

&lt;p&gt;As you switch modes, check if your text remains readable and whether icons, buttons, and accents are still visible. The goal is for both themes to look balanced, comfortable, and easy on the eyes.&lt;/p&gt;

&lt;p&gt;Next, test your color contrast ratio using WebAIM’s Contrast Checker. Copy your text and background colors from your CSS file (for example, #121212 and #E0E0E0) and paste them into the tool. Aim for a ratio of 4.5:1 or higher for normal text and 3:1 for larger text.&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%2Fdloif9pfan96snzll255.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%2Fdloif9pfan96snzll255.png" alt="Screenshot 2025-10-27 163158" width="740" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If your contrast ratio falls below the standard, adjust the colors slightly. Lighten the text or darken the background until the ratio improves. This small tweak makes a big difference for users with low vision or color sensitivity.&lt;/p&gt;

&lt;p&gt;You can also use accessibility tools for deeper testing. The Stark Plugin in Figma or Adobe XD simulates color blindness and checks contrast instantly. In Chrome, open DevTools → Lighthouse → Accessibility and click Analyze page load to get a detailed accessibility score. Firefox users can check the Accessibility Tab under Ctrl + Shift + I.&lt;/p&gt;

&lt;p&gt;Finally, perform a manual test. Turn on your room lights and review your page, is everything still clear? Then dim the lights or use your device’s dark mode and check again. If your page feels comfortable in both conditions, you’ve achieved true accessibility balance. &lt;/p&gt;

&lt;h2&gt;
  
  
  Case Studies &amp;amp; Best Practices
&lt;/h2&gt;

&lt;p&gt;Many popular platforms have already mastered dark mode accessibility. Studying their design choices helps you create your own high-quality, inclusive themes.&lt;/p&gt;

&lt;p&gt;GitHub, for example, uses dark gray backgrounds (#0D1117) instead of pure black. Its text (#C9D1D9) maintains strong contrast and consistency, ensuring comfort during long coding sessions. The key takeaway: readability always comes before aesthetics.&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%2Fqiflckek6r4ojnrdn4l0.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%2Fqiflckek6r4ojnrdn4l0.png" alt="Screenshot 2025-10-28 135632" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Slack takes a different approach by offering multiple dark themes. Users can choose what feels best for their eyes, proving that customization enhances accessibility. Choice empowers users with diverse vision needs.&lt;/p&gt;

&lt;p&gt;Notion uses layered contrasts and soft shadows to separate elements clearly. Its design demonstrates how visual hierarchy, not just color contrast improves readability in dark environments.&lt;/p&gt;

&lt;p&gt;When designing your own dark mode, avoid common mistakes. Don’t use pure black backgrounds with bright white text; they create harsh glare and eye strain. Steer clear of overly saturated accent colors or gray-on-gray combinations with poor contrast.&lt;/p&gt;

&lt;p&gt;Instead, use subtle elevation effects such as shadows or slightly lighter backgrounds to separate elements. This creates depth and readability without overwhelming the user’s eyes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Take your design further by adding smooth &lt;code&gt;CSS&lt;/code&gt;transitions when switching between light and dark modes. You can also detect user preferences automatically using the prefers-color-scheme media query.&lt;/p&gt;

&lt;p&gt;If possible, test your design with users who have color vision deficiencies or rely on assistive technologies like screen readers. Their feedback will help you refine your design for real-world use.&lt;/p&gt;

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

&lt;p&gt;You’ve successfully created and tested an accessible dark mode interface. You learned how to balance colors, ensure readability, and test for inclusivity. Now your design doesn’t just look modern, it works beautifully for everyone.   &lt;/p&gt;

&lt;p&gt;Designing an accessible dark mode interface isn’t just about trendy visuals, it’s about empathy and inclusion. A well-crafted dark theme supports users who are light-sensitive, work at night, or simply prefer darker interfaces, ensuring comfort and usability for everyone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Useful Resources&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/WCAG21/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;WCAG 2.1 Contrast Guidelines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/%40media/prefers-color-scheme?utm_source=chatgpt.com" rel="noopener noreferrer"&gt; MDN Web Docs: prefers-color-scheme&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://webaim.org/resources/contrastchecker/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Contrast Checker by WebAIM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.getstark.co/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Stark Accessibility Plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.chrome.com/docs/lighthouse/overview?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;Chrome DevTools Lighthouse&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;



</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Getting Started with LambdaTest: A Comprehensive Beginner’s Guide</title>
      <dc:creator>henry messiah tmt</dc:creator>
      <pubDate>Fri, 24 Oct 2025 23:11:35 +0000</pubDate>
      <link>https://dev.to/henry_messiahtmt_099ca84/getting-started-with-lambdatest-a-comprehensive-beginners-guide-4l2m</link>
      <guid>https://dev.to/henry_messiahtmt_099ca84/getting-started-with-lambdatest-a-comprehensive-beginners-guide-4l2m</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Today’s users expect flawless digital experiences, no matter which device, browser, or operating system they use. For developers and QA teams, ensuring that consistency across thousands of environments is no small feat.&lt;/p&gt;

&lt;p&gt;LambdaTest makes that challenge simple. It’s a powerful cloud based testing platform that enables effortless manual and automated cross browser testing on more than 3,000 real browsers and devices, all without the need for local setups or physical labs.&lt;/p&gt;

&lt;p&gt;Built for speed, scalability, and collaboration, LambdaTest integrates seamlessly with your existing CI/CD pipelines and popular tools like GitHub, Jenkins, and Jira. It supports leading automation frameworks such as Selenium, Cypress, Playwright, and Appium, empowering teams to test faster and release with confidence.&lt;/p&gt;

&lt;p&gt;From real time debugging and visual regression testing to comprehensive analytics, screenshots, and video logs, LambdaTest gives you everything you need to ensure your application looks and performs perfectly everywhere.&lt;/p&gt;

&lt;p&gt;In this Getting Started Guide, you’ll learn how to set up your account, navigate the dashboard, run your first manual and automated tests, and take your first steps toward a more efficient and reliable testing workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you begin, ensure you meet a few basic requirements to follow this guide smoothly. These will help you understand each step and execute your first test without issues.&lt;/p&gt;

&lt;p&gt;You’ll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js (v16+)&lt;/strong&gt; and npm installed on your system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basic JavaScript knowledge&lt;/strong&gt;: comfortable with functions and syntax&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Command line basics&lt;/strong&gt;: you’ll be running npm commands and navigating folders&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A modern browser&lt;/strong&gt;: Chrome, Firefox, or Edge for accessing the LambdaTest dashboard&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A stable internet connection&lt;/strong&gt;: required for all cloud based testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optional but helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Familiarity with manual or automated testing concepts&lt;/li&gt;
&lt;li&gt;Experience using any testing framework like Selenium or Cypress&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re missing any of these, take a moment to set them up first, so that we can flow together seamlessly. Once these prerequisites are in place, you’re ready to create your LambdaTest account and start your first testing session.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a LambdaTest Account
&lt;/h2&gt;

&lt;p&gt;Now that you’ve set up all the prerequisites, it’s time to step into the LambdaTest ecosystem by creating your personal account.&lt;/p&gt;

&lt;p&gt;Before you can start testing, you’ll need to set up your LambdaTest account which is your entry point to the cloud testing ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps to Get Started:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Visit &lt;a href="https://www.lambdatest.com/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;LambdaTest.com
&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click Sign Up for Free.&lt;/li&gt;
&lt;li&gt; Create an account using your email, Google, or GitHub credentials.&lt;/li&gt;
&lt;li&gt; Verify your email and log in to access your LambdaTest Dashboard.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;LambdaTest’s free plan includes limited testing minutes and parallel sessions, enough to explore its key features before deciding to upgrade.&lt;/p&gt;

&lt;p&gt;Once you’ve created your LambdaTest account, you’ll gain access to your personal dashboard, the command center where all your testing activities begin.&lt;/p&gt;

&lt;p&gt;Next, you’ll learn how to explore and navigate the dashboard to understand where key tools and settings are located.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explore the Dashboard
&lt;/h2&gt;

&lt;p&gt;Once logged in, the Dashboard serves as your central hub for all testing activities. It provides easy access to real time tests, automation suites, visual regression tools, and detailed analytics, all from a single, user friendly interface.&lt;/p&gt;

&lt;p&gt;From the Dashboard, You Can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Launch Real Time Tests on live browsers&lt;/li&gt;
&lt;li&gt;Run Automated Tests using your favorite framework&lt;/li&gt;
&lt;li&gt;Access Visual Regression Testing tools to track UI changes&lt;/li&gt;
&lt;li&gt;Review Test Logs &amp;amp; Analytics for detailed insights&lt;/li&gt;
&lt;li&gt;Integrate tools like GitHub, Jenkins, Jira, and Slack&lt;/li&gt;
&lt;li&gt;Use the left hand navigation panel to switch between features and manage your projects efficiently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what the dashboard looks like&lt;br&gt;
 &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq4hflh4m1et5re1ho99d.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%2Fq4hflh4m1et5re1ho99d.png" alt="lambdatest dashboard" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Run Your First Manual Test
&lt;/h2&gt;

&lt;p&gt;Now that you’re familiar with the dashboard layout and its core features, you’re ready to take action.&lt;/p&gt;

&lt;p&gt;In this step, you’ll learn how to run your first manual test, helping you see exactly how your website behaves across different browsers and operating systems in real time.&lt;/p&gt;

&lt;p&gt;Manual testing on LambdaTest allows you to visually verify your website’s appearance and performance across multiple browsers, operating systems, and screen resolutions, without local setups.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps to Run a Manual Test:&lt;/strong&gt;&lt;br&gt;
From the Dashboard, navigate to Real Time &amp;gt; Browser Testing.&lt;/p&gt;

&lt;p&gt;Enter your website’s URL (e.g., &lt;a href="https://example.com" rel="noopener noreferrer"&gt;https://example.com&lt;/a&gt;) in the URL input space provided.&lt;/p&gt;

&lt;p&gt;Select:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Operating System: Windows, macOS, or Linux&lt;/li&gt;
&lt;li&gt;Browser &amp;amp; Version: Chrome, Firefox, Safari, Edge, etc. &lt;/li&gt;
&lt;li&gt;Screen Resolution&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%2Fqhsqznn9rpfaoivnyq38.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%2Fqhsqznn9rpfaoivnyq38.png" alt="Screenshot 2025-10-19 204002" width="798" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click Start to launch a live browser session.&lt;/p&gt;

&lt;p&gt;Within seconds, LambdaTest opens your website in the selected environment. You can interact, inspect, and debug in real time, just like you would locally.&lt;/p&gt;

&lt;p&gt;Use the built in developer tools, capture screenshots, and record sessions to streamline debugging. The developer tools are shown in the image bellow &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffbcykak7xttl5lja0zc4.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%2Ffbcykak7xttl5lja0zc4.png" alt="developer tools" width="793" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next image shows how you can screenshot and record sessions.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9tszgmm2kdub7r2fnv6w.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%2F9tszgmm2kdub7r2fnv6w.png" alt="Screenshot 2025-10-21 114112" width="527" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After successfully performing your first manual test, you’ll understand how LambdaTest helps you verify the visual and functional consistency of your site.&lt;/p&gt;

&lt;p&gt;Next, you’ll take things a step further by learning how to automate your tests, saving time and improving efficiency across multiple test scenarios.&lt;/p&gt;
&lt;h2&gt;
  
  
  Run Your First Automated Test (Selenium Example)
&lt;/h2&gt;

&lt;p&gt;Having experienced manual testing, it’s time to take things to the next level with automation. &lt;/p&gt;

&lt;p&gt;Automated testing saves time and ensures reliability, especially for larger projects. LambdaTest supports major automation frameworks like Selenium, Cypress, Playwright, and Appium through its secure cloud grid.&lt;/p&gt;

&lt;p&gt;In this section, you’ll learn how to set up and run your first automated Selenium test on LambdaTest using &lt;code&gt;Node.js.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Set Up Your Environment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, make sure &lt;code&gt;Node.js&lt;/code&gt; (v16 or later) and &lt;code&gt;npm&lt;/code&gt; are installed on your system.&lt;br&gt;
If you have not installed &lt;code&gt;Node.js&lt;/code&gt; then follow these steps to install it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Windows users&lt;/strong&gt;&lt;br&gt;
Open PowerShell or Command Prompt and run the following command:&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;winget&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;OpenJS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NodeJS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LTS&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This installs the latest Long Term Support (LTS) version of &lt;code&gt;Node.js&lt;/code&gt; using the Windows Package Manager.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For macOS Users&lt;/strong&gt;&lt;br&gt;
If you already have &lt;code&gt;Homebrew&lt;/code&gt; installed, run the following command:&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;brew&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don’t have Homebrew yet, install it first by running this command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;bin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;bash&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once Homebrew finishes installing, use it to install &lt;code&gt;Node.js&lt;/code&gt; by running this command:&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;brew&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;For Both Windows and MacOS users&lt;/strong&gt;&lt;br&gt;
After installation we need to be sure that it was succefull. To verify that the installation was successful, open your terminal or command prompt and run the following commands:&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;node&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;
&lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If both commands return version numbers, you’re ready to proceed.&lt;br&gt;
If not, download and install&lt;code&gt;Node.js&lt;/code&gt; from nodejs.org&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a Project Folder&lt;/strong&gt;&lt;br&gt;
After verifying that the &lt;code&gt;Node.js&lt;/code&gt; installation was successful you can now create a project folder. You’ll need a folder to keep all your test files organized.&lt;/p&gt;

&lt;p&gt;In your terminal, run the following commands to creat a new folder called &lt;code&gt;lambdatest-automation&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;mkdir&lt;/span&gt; &lt;span class="nx"&gt;lambdatest&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;automation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, use the following command to navigate into the new folder we have called &lt;code&gt;lambdatest-automation&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="nx"&gt;lambdatest&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;automation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the above command we are now inside the new folder we created.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initialize a Node.js Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, initialize your project with &lt;code&gt;npm&lt;/code&gt; (Node Package Manager).&lt;br&gt;
This creates a &lt;code&gt;package.json&lt;/code&gt; file that tracks your project dependencies.&lt;br&gt;
To achieve that run the following command inside the project folder:&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;npm&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-y&lt;/code&gt; flag automatically accepts all default options.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install Selenium WebDriver&lt;/strong&gt;&lt;br&gt;
Next, install the Selenium library for JavaScript. To achieve that run the following command inside the project folder:&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;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;selenium&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;webdriver&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command downloads and installs Selenium into your project folder, allowing you to write and execute browser automation scripts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add Your LambdaTest Credentials&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before running tests, you need to provide your LambdaTest Username and Access Key.&lt;br&gt;
You can find them in your LambdaTest Dashboard under Profile → Account Settings → Access Key.&lt;/p&gt;

&lt;p&gt;The image below shows where to locate your credentials:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fssj5m7gal335pfydryoa.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%2Fssj5m7gal335pfydryoa.png" alt="profile details image" width="798" height="542"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you have them, add them as environment variables in your terminal.&lt;/p&gt;

&lt;p&gt;For Windows (PowerShell)run the following command in your project folder:&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;setx&lt;/span&gt; &lt;span class="nx"&gt;LT_USERNAME&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your_username&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="nx"&gt;setx&lt;/span&gt; &lt;span class="nx"&gt;LT_ACCESS_KEY&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your_access_key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For macOS/Linux run the following command in your project folder:&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;export&lt;/span&gt; &lt;span class="nx"&gt;LT_USERNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your_username&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;LT_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your_access_key&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This securely stores your credentials on your system so your test script can access them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create the Test File&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, create a new file named &lt;code&gt;lambdatest.js&lt;/code&gt;inside your project folder.&lt;/p&gt;

&lt;p&gt;If you’re using the terminal, run the following command:&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;touch&lt;/span&gt; &lt;span class="nx"&gt;lambdatest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now navigate into the test file using the following command:&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;cd&lt;/span&gt; &lt;span class="nx"&gt;lambdatest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(If you’re on Windows and touch doesn’t work, you can manually create the file in your folder using File Explorer.)&lt;/p&gt;

&lt;p&gt;Then, open the file in your preferred code editor (e.g., VS Code).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write Your Selenium Test Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Copy and paste the following code into &lt;code&gt;lambdatest.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Builder&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;selenium-webdriver&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;runTest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;capabilities&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;browserName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Chrome&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;browserVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;latest&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;LT:Options&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;platformName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Windows 10&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Getting Started Sample Build&lt;/span&gt;&lt;span class="dl"&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;My First LambdaTest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;user&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;LT_USERNAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;accessKey&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;LT_ACCESS_KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;usingServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://hub.lambdatest.com/wd/hub&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withCapabilities&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;capabilities&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;build&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;driver&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;https://www.lambdatest.com&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="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getTitle&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;driver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple script launches Chrome on Windows 10 in the LambdaTest cloud, opens the LambdaTest homepage, prints its title, and closes the session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run the Test&lt;/strong&gt;&lt;br&gt;
You’re now ready to execute your first automated test!&lt;br&gt;
From your project folder, run the following command:&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;node&lt;/span&gt; &lt;span class="nx"&gt;lambdatest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command tells &lt;code&gt;Node.js&lt;/code&gt; to execute your Selenium script.&lt;/p&gt;

&lt;p&gt;Once the test starts, LambdaTest will automatically open a cloud browser session and run your test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;View Your Test Session&lt;/strong&gt;&lt;br&gt;
After running the test, go to your LambdaTest Dashboard → Automation → Test Logs.&lt;br&gt;
You’ll see your session appear under “Recent Tests.”&lt;/p&gt;

&lt;p&gt;Click the session to view:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Logs: Console and network logs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Screenshots &amp;amp; Video Recordings: To review test execution&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Session Details: Browser, OS, build name, and duration&lt;/p&gt;&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%2Fr1miw29a0u72c40mc5ua.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%2Fr1miw29a0u72c40mc5ua.png" alt="Screenshot 2025-10-20 154922" width="531" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Smart UI for Visual Testing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;LambdaTest’s Smart UI feature helps detect pixel level visual differences between builds.&lt;br&gt;
You can enable it from the Automation Dashboard to ensure your design remains consistent across updates.&lt;/p&gt;

&lt;p&gt;By reviewing your test data, you’ll learn how to identify bugs, confirm design accuracy, and maintain UI consistency across multiple browsers.&lt;/p&gt;

&lt;p&gt;Use the Smart UI feature to perform visual regression testing, detecting pixel level UI discrepancies between builds for consistent design validation.&lt;/p&gt;

&lt;p&gt;After reviewing your results, you’ll know how to analyze test data, identify issues, and confirm visual accuracy using Smart UI.&lt;/p&gt;

&lt;p&gt;Next, you’ll learn how to troubleshoot common issues, ensuring that any challenges you encounter can be quickly resolved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting Common Issues
&lt;/h2&gt;

&lt;p&gt;When using LambdaTest, you might occasionally run into problems while running your tests. Here’s a breakdown of some common issues, their likely causes, and how you can fix them effectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Session Not Starting&lt;/strong&gt;&lt;br&gt;
If your test session fails to start, the most common reason is invalid credentials. LambdaTest requires your correct username and access key to authenticate with its servers. Double check these details under Profile → Account Settings on your dashboard, and ensure that your environment variables (LT_USERNAME and LT_ACCESS_KEY) are properly set in your system before running any test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Browser Not Launching&lt;/strong&gt;&lt;br&gt;
Sometimes, the browser you select may not open during testing. This often happens when you’ve chosen an unsupported browser version. To resolve this, verify that the browser and version combination you’re using is supported by LambdaTest. You can find a complete list of supported browsers and OS combinations on their platform documentation or within the test configuration panel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Test Timeout&lt;/strong&gt;&lt;br&gt;
If your tests are failing due to timeouts, it’s likely a result of network latency or slow website responses. To fix this, consider increasing the timeout duration in your test script. You can adjust Selenium’s implicit or explicit wait times to give your pages more time to load. It’s also worth ensuring your internet connection is stable before initiating long test runs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Localhost Not Loading&lt;/strong&gt;&lt;br&gt;
When testing locally hosted websites or staging environments, you might encounter problems accessing your localhost URL. This usually means the LambdaTest Tunnel isn’t configured correctly. The tunnel acts as a secure bridge between your local system and LambdaTest’s cloud grid. To solve this, install and run the LambdaTest Tunnel binary, then verify that it’s connected successfully before starting your tests.&lt;/p&gt;

&lt;p&gt;If you continue to experience issues after trying these fixes, visit the LambdaTest Support Center&lt;br&gt;
 for detailed documentation, community discussions, and real-time help from their &lt;a href="https://www.lambdatest.com/support/docs/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;support team&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By learning to troubleshoot common testing challenges, you’ll become more confident in managing and optimizing your testing sessions.&lt;/p&gt;

&lt;p&gt;Next, you’ll explore advanced LambdaTest features and integrations, empowering you to streamline testing workflows and enhance team collaboration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Congratulations, you’ve run your first manual and automated tests! To take your skills further, explore these advanced capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Parallel Testing:&lt;/strong&gt; Execute multiple tests simultaneously to speed up your testing cycle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CI/CD Integrations:&lt;/strong&gt; Connect LambdaTest with Jenkins, GitHub Actions, or Azure DevOps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Visual Regression Testing:&lt;/strong&gt; Automatically detect UI inconsistencies between builds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Local App Testing:&lt;/strong&gt; Use LambdaTest Tunnel to test staging or internal environments securely.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With a solid foundation in manual and automated testing, you’re ready to expand your testing strategy.&lt;/p&gt;

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

&lt;p&gt;By following this guide, you’ve learned how to create and set up your LambdaTest account. You now know how to configure your workspace and testing environment. This ensures a smooth start as you begin running tests across browsers and devices.&lt;/p&gt;

&lt;p&gt;You’ve also explored how to navigate the LambdaTest dashboard efficiently. Its clean layout makes it easy to access real-time tests, automation tools, and analytics. With this, managing sessions and reviewing results becomes quick and intuitive.&lt;/p&gt;

&lt;p&gt;Lastly, you’ve mastered running both manual and automated tests while learning to analyze logs and troubleshoot issues. These skills prepare you to integrate LambdaTest into your CI/CD workflow. Now you can deliver faster, more reliable, and consistent digital experiences.&lt;/p&gt;

&lt;p&gt;For more detailed information and advanced configurations, you can visit the &lt;a href="https://www.lambdatest.com/support/docs/?utm_source=chatgpt.com" rel="noopener noreferrer"&gt;official LambdaTest Documentation&lt;/a&gt; page to explore further.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>testing</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Automating Jasmine Tests with GitHub Actions for Continuous Integration</title>
      <dc:creator>henry messiah tmt</dc:creator>
      <pubDate>Sat, 18 Oct 2025 16:19:19 +0000</pubDate>
      <link>https://dev.to/henry_messiahtmt_099ca84/automating-jasmine-tests-with-github-actions-for-continuous-integration-53gn</link>
      <guid>https://dev.to/henry_messiahtmt_099ca84/automating-jasmine-tests-with-github-actions-for-continuous-integration-53gn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Manual testing can quickly become a problem in your development workflow. Every time you need to remember to run tests. This process would not only waste valuable time but also increase the risk of human error; it's quite very common to forget a test or accidentally merge faulty code when you're in a hurry.&lt;/p&gt;

&lt;p&gt;That's why this article is important because it introduces how you integrate Jasmine tests with GitHub Actions to create a fully automated testing pipeline, and walks through how to write sample tests and automate them to run on every push or pull request made in your future projects. So you no longer manually run your test, you push with a crossed finger, hoping you pass.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before diving into this tutorial, you'll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js (v16+) and npm installed on your machine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basic JavaScript knowledge&lt;/strong&gt; - You should be comfortable writing functions and understanding basic syntax&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Git fundamentals&lt;/strong&gt; - Know how to commit, push, and work with branches&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A GitHub account&lt;/strong&gt; - Required for setting up GitHub Actions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Command line basics&lt;/strong&gt; - You'll be running npm commands and navigating directories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Optional but helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Familiarity with testing concepts (though we'll cover the basics)&lt;/li&gt;
&lt;li&gt;Previous experience with any testing framework&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're missing any of these, take some time to set them up first. Everything else we'll build together from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up your project
&lt;/h2&gt;

&lt;p&gt;First, we need to set up a new Node.js project. This will create a &lt;code&gt;package.json&lt;/code&gt; file, which keeps track of all dependencies and scripts for our project.&lt;br&gt;
Open your terminal (or command prompt) and follow these steps:&lt;br&gt;
Create a new folder for the project using the following command&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;mkdir&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate into the project folder using the following command&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;cd&lt;/span&gt; &lt;span class="nx"&gt;project&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Initialize a new Node.js project inside the folder using the following command&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;npm&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command initializes a Node.js project with default settings and automatically generates a &lt;code&gt;package.json&lt;/code&gt; file inside your project directory.&lt;/p&gt;

&lt;p&gt;Next, we will need to install Jasmine as a development dependency. To do that, run this command in the project folder.&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;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;jasmine&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To initialize Jasmine, you will need to run this command in the project folder.&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;npx&lt;/span&gt; &lt;span class="nx"&gt;jasmine&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you do, you will see a default configuration file named &lt;code&gt;jasmine.json.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now that we have successfully installed and initialized Jasmine, we need to create a simple test to confirm that &lt;strong&gt;Jasmine&lt;/strong&gt; is working correctly in our project. To do that, follow these steps:&lt;/p&gt;

&lt;p&gt;Create a new folder called &lt;code&gt;spec&lt;/code&gt; inside your project directory. This is where Jasmine expects your test files to be stored. Use this command to create the spec folder&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;mkdir&lt;/span&gt; &lt;span class="nx"&gt;spec&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate into the &lt;code&gt;spec&lt;/code&gt; folder using the following command&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;cd&lt;/span&gt; &lt;span class="nx"&gt;spec&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the spec folder, create a new test file named &lt;code&gt;sampleSpec.js&lt;/code&gt; using this command&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;touch&lt;/span&gt; &lt;span class="nx"&gt;sampleSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re on Windows and &lt;code&gt;touch&lt;/code&gt; doesn’t work, 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="nx"&gt;echo&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;sampleSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the &lt;code&gt;sampleSpec.js&lt;/code&gt; file in your code editor and add the following test code:&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="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sample Test&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;adds numbers correctly&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple test checks if &lt;code&gt;1 + 1&lt;/code&gt; equals &lt;code&gt;2&lt;/code&gt;. If Jasmine is set up correctly, this test will &lt;strong&gt;pass&lt;/strong&gt; when you run it.&lt;/p&gt;

&lt;p&gt;Finally, run your test locally. This verifies that Jasmine is correctly installed and configured. Let’s run the following command in our terminal:&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;npx&lt;/span&gt; &lt;span class="nx"&gt;jasmine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A passing test confirms that your setup is complete and ready for CI integration. When your tests run successfully, Jasmine will display green indicators showing that all checks have passed, just like in the image below.&lt;/p&gt;

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

&lt;p&gt;However, not all tests are meant to pass immediately. Sometimes, developers intentionally write &lt;strong&gt;failing tests&lt;/strong&gt; to verify that Jasmine correctly detects errors or to test incomplete features under development. These failing tests serve as a guide, reminding you of areas that still need attention or improvement. Once the issue is resolved or the feature is implemented, those tests should then pass, confirming that your fix or new functionality works as expected.&lt;br&gt;
This balance between passing and expected failing tests is a key part of effective test-driven development, ensuring your project grows with confidence and precision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example folder structure&lt;/strong&gt;&lt;br&gt;
Now that you’ve successfully set up and tested your Jasmine environment, it’s important to organize your files for better clarity and maintainability.&lt;br&gt;
Use this structure as a reference:&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;project&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="err"&gt;│&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;spec&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;sampleSpec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="kr"&gt;package&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;
    &lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;jasmine&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;
    &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;github&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
        &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;workflows&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
            &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;yml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This layout separates your test files, source code, and CI configurations clearly. It helps you and your team maintain order as your project grows.&lt;br&gt;
Now that we have neatly organized files, you can proceed to automate the testing process using GitHub Actions.&lt;/p&gt;
&lt;h2&gt;
  
  
  Add GitHub Actions workflow
&lt;/h2&gt;

&lt;p&gt;With your project structure in place, the next step is to automate your testing process. By using GitHub Actions, you can ensure your Jasmine tests run automatically whenever you push new code or open a pull request.&lt;/p&gt;

&lt;p&gt;Create a workflow file at &lt;code&gt;.github/workflows/test.yml.&lt;/code&gt; This file tells GitHub Actions what to do during each run.&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Run&lt;/span&gt; &lt;span class="nx"&gt;Jasmine&lt;/span&gt; &lt;span class="nx"&gt;Tests&lt;/span&gt;

    &lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;pull_request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="nx"&gt;jobs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nx"&gt;runs&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ubuntu&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;latest&lt;/span&gt;

        &lt;span class="nx"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
          &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Checkout&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt;
            &lt;span class="nx"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;v4&lt;/span&gt;

          &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt; &lt;span class="nx"&gt;up&lt;/span&gt; &lt;span class="nx"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
            &lt;span class="nx"&gt;uses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;v4&lt;/span&gt;
            &lt;span class="kd"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
              &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;20&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

          &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Install&lt;/span&gt; &lt;span class="nx"&gt;dependencies&lt;/span&gt;
            &lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;npm&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt;

          &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Run&lt;/span&gt; &lt;span class="nx"&gt;tests&lt;/span&gt;
            &lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;npx&lt;/span&gt; &lt;span class="nx"&gt;jasmine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each step performs a key task:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Checkout code&lt;/code&gt; downloads your repository to the workflow runner.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Set up Node.js&lt;/code&gt; ensure the correct runtime version.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Install dependencies&lt;/code&gt; gets all required packages.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Run tests&lt;/code&gt; executes Jasmine to validate your code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setup guarantees that your code is tested automatically on every commit.&lt;br&gt;
Now that the automation workflow is ready, the next step is to push your code to GitHub and trigger the workflow in action.&lt;/p&gt;
&lt;h2&gt;
  
  
  Trigger the workflow
&lt;/h2&gt;

&lt;p&gt;You’ve defined your CI workflow, now it’s time to see it work. Committing and pushing your files to GitHub connects your project to the automated testing pipeline.&lt;/p&gt;

&lt;p&gt;Commit your files and push them to the main branch:&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;git&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;
    &lt;span class="nx"&gt;git&lt;/span&gt; &lt;span class="nx"&gt;commit&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Set up Jasmine CI workflow&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="nx"&gt;git&lt;/span&gt; &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="nx"&gt;origin&lt;/span&gt; &lt;span class="nx"&gt;main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each push triggers the workflow defined in &lt;code&gt;test.yml.&lt;/code&gt; GitHub Actions installs dependencies and runs your tests automatically. Now that your workflow has been triggered, let’s verify that it runs successfully and that your tests pass as expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify the workflow
&lt;/h2&gt;

&lt;p&gt;At this point, your tests should be running automatically in GitHub Actions. It’s important to confirm that everything executes correctly and that your CI pipeline is stable.&lt;br&gt;
Follow these steps to verify: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open your repository on GitHub.&lt;/li&gt;
&lt;li&gt;Click the Actions tab.&lt;/li&gt;
&lt;li&gt;Select your workflow from the list.&lt;/li&gt;
&lt;li&gt;Check the log to confirm that all steps completed and tests passed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The image below shows what it will look like:&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%2Fmtrsuwbfirwn3qytouz1.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%2Fmtrsuwbfirwn3qytouz1.jpg" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If any step fails, review the logs to identify configuration or test issues. Fixing them early prevents broken code from merging.&lt;/p&gt;

&lt;p&gt;Once you’ve confirmed that your workflow works, you can optionally add a visual indicator to your repository, a status badge that shows whether your tests are passing or failing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add test status badges (optional)
&lt;/h2&gt;

&lt;p&gt;Now that your CI pipeline is up and running, adding a status badge provides instant visibility into your project’s health. Badges are especially useful for open-source projects and team collaboration.&lt;br&gt;
Add this line to your &lt;code&gt;README.md&lt;/code&gt; file: &lt;a href="https://github.com/your-username/your-repo/actions/workflows/test.yml/badge.svg" rel="noopener noreferrer"&gt;https://github.com/your-username/your-repo/actions/workflows/test.yml/badge.svg&lt;/a&gt;. This will show the status of the test if passed or failed:&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%2Fw684ufeg04gi2u63jajz.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%2Fw684ufeg04gi2u63jajz.jpg" alt="Test barge" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The badge updates automatically after every workflow run. This adds visibility and helps collaborators monitor build status at a glance. With your automated workflow complete, let’s look at a few best practices to make your testing process more reliable and efficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips for reliable testing
&lt;/h2&gt;

&lt;p&gt;Now that your Jasmine tests run automatically with each commit, maintaining consistency and reliability becomes crucial. Following these best practices ensures that your CI pipeline stays &lt;strong&gt;fast, dependable, and easy to maintain&lt;/strong&gt; over time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Keep tests small and independent&lt;/strong&gt;&lt;br&gt;
Write focused tests that check one specific functionality at a time. This makes it easier to identify which part of your code is failing when an error occurs. Independent tests can run in any order without affecting each other, which improves accuracy and speeds up debugging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Avoid relying on external data sources&lt;/strong&gt;&lt;br&gt;
Tests should not depend on external APIs, databases, or network connections. These can introduce delays or failures unrelated to your actual code. Instead, use mock data or stubs to simulate external responses, ensuring that your tests remain stable even when you’re offline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Run tests locally before committing&lt;/strong&gt;&lt;br&gt;
Always run your Jasmine tests locally before pushing code to your repository. This helps you catch issues early, saving time and preventing unnecessary CI failures. A quick local test run ensures that only clean, working code reaches your remote branch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Cache dependencies in CI for faster execution&lt;/strong&gt;&lt;br&gt;
Most CI systems (like GitHub Actions) allow you to &lt;strong&gt;cache dependencies&lt;/strong&gt; such as &lt;code&gt;node_modules&lt;/code&gt;. Caching means that repeated builds won’t reinstall all packages from scratch, significantly reducing test run times and improving overall pipeline efficiency.&lt;/p&gt;

&lt;p&gt;By applying these practices, your automated testing workflow becomes more &lt;strong&gt;reliable, efficient, and scalable&lt;/strong&gt;. You’ll spend less time fixing broken builds and more time focusing on writing high-quality, maintainable code.&lt;/p&gt;

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

&lt;p&gt;You now understand how to install essential dependencies, configure Jasmine for your project, and create a workflow that runs tests automatically with every push or pull request. More importantly, you’ve seen how continuous integration helps detect bugs early, keeps your code clean, and verifies every change before merging all without manual intervention.&lt;/p&gt;

&lt;p&gt;Applying what you’ve learned will greatly improve your workflow. Automated testing reduces errors, accelerates feedback, and boosts confidence in your codebase. With Jasmine and GitHub Actions working together, you’ve built a strong foundation for reliability and efficiency in every update.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>From Pills to Programming: My Journey from Pharmacy to Software Development</title>
      <dc:creator>henry messiah tmt</dc:creator>
      <pubDate>Sun, 05 Oct 2025 20:31:20 +0000</pubDate>
      <link>https://dev.to/henry_messiahtmt_099ca84/from-pills-to-programming-my-journey-from-pharmacy-to-software-development-3pae</link>
      <guid>https://dev.to/henry_messiahtmt_099ca84/from-pills-to-programming-my-journey-from-pharmacy-to-software-development-3pae</guid>
      <description>&lt;p&gt;My journey began in the structured halls of pharmacy school, where science met service, and every formula represented a step toward saving lives. As a young student, I was driven by a passion for health care and a desire to make meaningful contributions to society. I poured my energy into learning and service, graduating as the &lt;strong&gt;second-best student in my class with honors,&lt;/strong&gt; a recognition that did not just reward academic excellence, but also my discipline, resilience, and vision for the future.&lt;br&gt;
After pharmacy school, I channeled my passion into entrepreneurship, founding &lt;strong&gt;Mexicare Pharmacy and Co. Ltd.&lt;/strong&gt; As CEO, I was not just responsible for medicines and prescriptions, but for building a brand rooted in trust, innovation, and excellence. Managing a business required me to go beyond clinical knowledge. I had to understand people, logistics, technology, and leadership. That experience taught me how to balance precision with empathy and structure with adaptability.&lt;br&gt;
Yet, my thirst for knowledge did not stop at the pharmacy counter. I pursued a &lt;strong&gt;Master’s degree in Clinical Pharmacy,&lt;/strong&gt; deepening my expertise in pharmacotherapy and patient-centered care. To complement this, I ventured into the field of &lt;strong&gt;health informatics,&lt;/strong&gt; an intersection of health and computer science. This was my first formal step into the world of data and algorithms, and it opened my eyes to the power of computation in solving real-world health problems.&lt;br&gt;
It was during my graduate studies that I developed a keen interest in &lt;strong&gt;data analysis&lt;/strong&gt;. I trained in tools like &lt;strong&gt;Excel, SPSS, and GraphPad,&lt;/strong&gt; learning to translate complex datasets into meaningful insights. I discovered how numbers can tell stories, predict outcomes, and shape decisions. This phase sharpened my analytical thinking and laid a strong foundation for the next chapter of my journey.&lt;br&gt;
Now, I am stepping boldly into the world of software development, equipped with foundational and intermediate skills in &lt;strong&gt;HTML, CSS, JavaScript, and React.js.&lt;/strong&gt; What began as curiosity has evolved into a new passion, a desire to build, create, and innovate in the digital space. Software development excites me because it offers limitless possibilities. Just as I once compounded formulas for healing, I now write code that solves problems, connects people, and enhances lives.&lt;br&gt;
As part of my transition into tech, I have built several projects that demonstrate my growing expertise and creativity. These include a personal portfolio website that showcases my work and skills; a weather app that provides real-time weather conditions for any city; a digital stopwatch; an interactive rock-paper-scissors game; a digital clock; and an Amazon clone website built with React and modern web development principles. Each of these projects taught me how to think like a &lt;strong&gt;software developer&lt;/strong&gt;, focusing on functionality, user experience, and scalability.&lt;br&gt;
Alongside coding, I have developed a strong interest in &lt;strong&gt;technical writing,&lt;/strong&gt; which is the art of explaining complex technical concepts with clarity and precision. Through my articles and documentation, I aim to make technology more accessible to beginners while maintaining the accuracy professionals expect. I’ve written step-by-step guides on building JavaScript projects and creating responsive interfaces, honing my ability to communicate effectively across both technical and non-technical audiences. Example of such an article published in dev. to is &lt;a href="https://dev.to/henry_messiahtmt_099ca84/how-to-create-a-digital-clock-using-javascript-4fec"&gt;How to build a digital clock using JavaScript.&lt;/a&gt;&lt;br&gt;
My path may seem unconventional, from clinical pharmacy to entrepreneurship, from health informatics to programming, but at the heart of it all is a commitment to growth and impact. Each stage has equipped me with unique tools: precision from pharmacy, leadership from business, analysis from research, and creativity from coding.&lt;br&gt;
I do not see this as a career change, but rather a career evolution. Today, as I continue learning and building in tech, I carry with me the discipline of a pharmacist, the vision of a CEO, the curiosity of a researcher, the clarity of a technical writer, and the innovation of a software engineer.&lt;br&gt;
&lt;strong&gt;This is my story, and it is only just beginning.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>How To Create A Digital Clock Using JavaScript</title>
      <dc:creator>henry messiah tmt</dc:creator>
      <pubDate>Sun, 05 Oct 2025 16:49:09 +0000</pubDate>
      <link>https://dev.to/henry_messiahtmt_099ca84/how-to-create-a-digital-clock-using-javascript-4fec</link>
      <guid>https://dev.to/henry_messiahtmt_099ca84/how-to-create-a-digital-clock-using-javascript-4fec</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Time is everywhere, on our phones, computers, and even our microwaves. But have you ever wondered how a digital clock actually works behind the scenes? Building a digital clock with JavaScript is not only a fun, beginner-friendly project but also an excellent way to strengthen your understanding of real-time updates, DOM manipulation, and event-driven programming.&lt;/p&gt;

&lt;p&gt;In this guide, you’ll learn how to create a fully functional digital clock from scratch using just HTML, CSS, and JavaScript. By the end, you’ll have a sleek clock that updates automatically every second, perfect for embedding in a webpage, dashboard, or even as a standalone utility.&lt;/p&gt;

&lt;p&gt;Whether you are just starting your coding journey or looking to sharpen your JavaScript skills, this project will help you achieve the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Master working with Date objects.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Practice dynamic content updates using the DOM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enhance your styling and layout skills with CSS.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s get started and bring your own digital clock to life. &lt;/p&gt;

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

&lt;p&gt;Before we dive into writing the code, we need to set up a simple working environment for our digital clock. This project is lightweight and doesn’t require any special frameworks or tools; all you need is your browser and a text editor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a Project Folder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a new folder on your computer and name it &lt;code&gt;digital-clock&lt;/code&gt;. This will keep all your project files organized.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create the Essential Files&lt;/strong&gt;&lt;br&gt;
After creating the folder that will keep all our files together, we can now create the different files we need.&lt;/p&gt;

&lt;p&gt;Inside your project folder, which we have named digital-clock, create the following files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;index.html&lt;/code&gt;This will contain the structure of the clock.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;clock.css&lt;/code&gt;This will handle the visual design of the clock.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;clock.js&lt;/code&gt; This will contain the JavaScript logic that makes the clock work.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your project folder should now look 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;digital-clock/
  ├── index.html
  ├── clock.css
  └── clock.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we are done with the project, this is what the digital clock will look like.&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%2Ft1ewwqbhpzq9bb8huown.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%2Ft1ewwqbhpzq9bb8huown.png" alt="the digital clock" width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't forget to link the &lt;code&gt;clock.css&lt;/code&gt; and the &lt;code&gt;clock.js&lt;/code&gt; files to the &lt;code&gt;index.html&lt;/code&gt;file properly.&lt;br&gt;
  Link the &lt;code&gt;clock.css&lt;/code&gt; inside the &lt;code&gt;HTML&lt;/code&gt; &lt;/p&gt; with  then Link the &lt;code&gt;clock.js&lt;/code&gt;before the closing  tag with .
&lt;h2&gt;
  
  
  Build The HTML Structure
&lt;/h2&gt;

&lt;p&gt;Now that our project setup is complete and we have all the necessary files ready, it’s time to start building the foundation of our digital clock, the HTML structure.&lt;/p&gt;

&lt;p&gt;This step focuses on creating the basic layout that will display the time on the webpage. It defines what elements appear on the page and how they are organized.&lt;/p&gt;

&lt;p&gt;We’ll be adding simple elements that represent the digital clock display, which we’ll later style using CSS and make interactive with JavaScript.&lt;/p&gt;

&lt;p&gt;Let’s dive into the HTML part of our project and bring the structure of our digital clock to life.&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;index.html&lt;/code&gt; file and write the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="nx"&gt;DOCTYPE&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UTF-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viewport&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;width=device-width, initial-scale=0.5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;digital&lt;/span&gt; &lt;span class="nx"&gt;clock&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/title&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stylesheet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clock.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/head&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clock-container&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clock.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/body&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/html&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add The CSS Code
&lt;/h2&gt;

&lt;p&gt;Now that we’ve built the structure of our digital clock using HTML, it’s time to make it visually appealing with CSS.&lt;/p&gt;

&lt;p&gt;While HTML gives our project its form, CSS adds style, color, and aesthetics, turning a plain layout into an attractive digital display. In this step, we’ll design the clock to look clean, centered, easy to read, and add a background image.&lt;/p&gt;

&lt;p&gt;We’ll focus on aligning the clock at the center of the screen, choosing the right font, and giving it a glowing digital feel.&lt;/p&gt;

&lt;p&gt;Let’s move on and make the clock beautiful with some sleek and responsive styling using CSS.&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;clock.css&lt;/code&gt; file and add the following code&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;body&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;premium_photo&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1661954654458&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;c673671d4a08&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;avif&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;attachment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fixed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;clock&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;justify&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;align&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="nx"&gt;vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;clock&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;monospace&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;6.5&lt;/span&gt;&lt;span class="nx"&gt;rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;weight&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;text&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;backdrop&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;background&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;hsl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;At this stage, the digital clock looks exactly as our final product above, but it is not functional. &lt;/p&gt;

&lt;h2&gt;
  
  
  Add The JavaScript Logic
&lt;/h2&gt;

&lt;p&gt;With the structure and styling in place, our digital clock now looks great, but it doesn’t tick yet. To make it come alive and update in real time, we need to add the JavaScript logic.&lt;/p&gt;

&lt;p&gt;JavaScript is the brain of our project. It’s what allows the clock to fetch the current time, update the numbers every second, and display the hours, minutes, and seconds dynamically.&lt;/p&gt;

&lt;p&gt;In this section, we’ll write the code that powers the functionality behind the clock, ensuring it runs smoothly and reflects the exact time on your device, just like a real digital clock.&lt;/p&gt;

&lt;p&gt;Let’s dive in and give our clock its heartbeat with JavaScript.&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;clock.js&lt;/code&gt; file and add the following code.&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;updateClock&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&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;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;hours&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getHours&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;meridien&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hours&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;PM&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;AM&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;hours&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hours&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;12&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="nx"&gt;hours&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&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;minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMinutes&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&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;seconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSeconds&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;padStart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&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;timeString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hours&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;seconds&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;meridien&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;clock&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;timeString&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;updateClock&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updateClock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A link to the fully functional clock is available &lt;a href="https://tmt-digitalclock.netlify.app/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  User Interface Overview
&lt;/h2&gt;

&lt;p&gt;The user interface of our digital clock is designed to be clean, elegant, and easy to read. The background image fills the entire screen, creating a modern and visually appealing environment, while the clock itself is centered perfectly on the page using CSS Flexbox. This ensures the layout remains balanced and responsive across all screen sizes from desktops to mobile devices.&lt;/p&gt;

&lt;p&gt;At the center of the screen, the clock displays bold white digits in a monospace font, giving it a classic digital appearance. The large font size and even spacing make the time clearly visible at a glance. A subtle blur and semi-transparent background sit behind the clock, creating a smooth, glasslike effect that highlights the numbers and enhances readability regardless of the background image.&lt;/p&gt;

&lt;p&gt;When the JavaScript logic runs, the clock updates automatically every second, bringing the interface to life with real-time motion. The result is a simple yet sophisticated digital clock that combines functionality with a sleek, modern design, perfect for embedding in any webpage or dashboard.&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%2Far7uao80k26pyxc380xr.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%2Far7uao80k26pyxc380xr.png" alt=" " width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Building a digital clock with HTML, CSS, and JavaScript is a simple yet powerful project that brings together the core principles of front-end development, which include structure, style, and interactivity. Through this project, you’ve learned how to use JavaScript’s &lt;code&gt;Date&lt;/code&gt; object to track real-time updates, manipulate the DOM to display dynamic content, and apply CSS to craft a clean, responsive design.&lt;/p&gt;

&lt;p&gt;Beyond just displaying time, this project demonstrates how a few lines of code can transform basic concepts into a visually engaging and functional application. You can now take what you’ve learned and expand it, add new features, experiment with different designs, or even integrate it into a larger web project. With every enhancement, you’ll continue sharpening your coding skills and developing a stronger understanding of how JavaScript brings web pages to life.&lt;/p&gt;

&lt;p&gt;Although the digital clock works perfectly, it can be enhanced with features like a date display, theme customization, and options to switch between 12-hour and 24-hour formats. Adding smooth animations, time zone selection, or dynamic greetings such as “Good Morning” or “Good Night” would make it more interactive, while expanding it with a countdown timer or stopwatch could turn it into a versatile time utility, all great ways to strengthen your JavaScript and front-end development skills further.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>softwaredevelopment</category>
      <category>coding</category>
      <category>software</category>
    </item>
    <item>
      <title>How To Build A Note Taking Application With JavaScript</title>
      <dc:creator>henry messiah tmt</dc:creator>
      <pubDate>Sun, 28 Sep 2025 13:28:50 +0000</pubDate>
      <link>https://dev.to/henry_messiahtmt_099ca84/how-to-build-a-note-taking-application-with-javascript-4053</link>
      <guid>https://dev.to/henry_messiahtmt_099ca84/how-to-build-a-note-taking-application-with-javascript-4053</guid>
      <description>&lt;p&gt;Building software often starts with solving everyday problems. One common problem is how to keep track of important information. People take notes during meetings, while studying, or when planning personal tasks. Paper notes get lost, and static files are hard to update. A digital note taking app offers a practical solution.&lt;/p&gt;

&lt;p&gt;A note taking app allows you to create, edit, organize, and store notes in one place. It helps you keep information structured and easy to access. With simple features, you can add a title, write your content, assign tags, and search through your notes later. Storing notes in local storage ensures that your data remains available even after closing the browser.&lt;/p&gt;

&lt;p&gt;This tutorial will guide you through the process of building a note taking app using JavaScript, HTML, and CSS. You will learn how to:&lt;br&gt;
• Create a user interface for writing and displaying notes&lt;br&gt;
• Add functionality to create, edit, and delete notes&lt;br&gt;
• Build a search feature to filter notes by keywords or tags&lt;br&gt;
• Store and retrieve notes using local storage&lt;br&gt;
• Add a web clipping feature to save selected webpage text into your notes&lt;br&gt;
By following these steps, you will complete a working note taking application that runs directly in the browser and supports practical features for managing your notes efficiently.&lt;/p&gt;
&lt;h2&gt;
  
  
  System Requirements
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Browser Compatibility&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;• Google Chrome (recommended).&lt;br&gt;
• Mozilla Firefox.&lt;br&gt;
• Microsoft Edge.&lt;br&gt;
• Safari.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependencies&lt;/strong&gt;&lt;br&gt;
• None. The app uses pure HTML, CSS, and JavaScript (no frameworks required).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Technologies Used:&lt;/strong&gt; An outline of the foundational web technologies needed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  HTML5 (for structuring the app)&lt;/li&gt;
&lt;li&gt;  CSS3 (for styling)&lt;/li&gt;
&lt;li&gt;JavaScript (for functionality)&lt;/li&gt;
&lt;li&gt;  Browser Local Storage (for data persistence) &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Project Setup
&lt;/h2&gt;

&lt;p&gt;Now that we have installed all basic requirements, we can now proceed to set up the project structure in our code editor.&lt;/p&gt;

&lt;p&gt;At this stage we will learn how to open folder and arrange the file structure of the project. To do that, follow the steps bellow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Folder structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is how the folder structure will look like.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;note-taking-app/
  index.html
  style.css
  script.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;&lt;br&gt;
Let us follow these steps to create the folder and the files to structure our project.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a folder named note-taking-app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Inside it, add three files: &lt;code&gt;index.html,&lt;/code&gt; &lt;code&gt;style.css,&lt;/code&gt; and &lt;code&gt;script.js&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link &lt;code&gt;style.css&lt;/code&gt; inside the HTML &lt;code&gt;&amp;lt;head&amp;gt; with &amp;lt;link rel="stylesheet" href="style.css"&amp;gt;.&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link &lt;code&gt;script.js&lt;/code&gt; before the closing &lt;code&gt;&amp;lt;/body&amp;gt; tag with &amp;lt;script src="script.js"&amp;gt;&amp;lt;/script&amp;gt;.&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;At the end of the project, if you follow the exact codes bellow, this is what the product would look like. &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%2Fcb8y4fo4jtg8t65ujiew.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%2Fcb8y4fo4jtg8t65ujiew.PNG" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Build the HTML Structure
&lt;/h2&gt;

&lt;p&gt;Now that we have created the folder and the files required for the project, we will now start to write the codes for the project.&lt;/p&gt;

&lt;p&gt;In this step, we will write the HTML codes for the project, the html codes will determine the physical appearance of the project. Follow the steps bellow and write the codes to achieve the desired result. &lt;/p&gt;

&lt;p&gt;Open the&lt;code&gt;index.html file&lt;/code&gt; and add the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="nx"&gt;doctype&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="nx"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;charset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf-8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;viewport&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;width=device-width,initial-scale=1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Notes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/title&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="nx"&gt;rel&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;stylesheet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;style.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/head&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Notes&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;controls&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;search&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Search notes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;newNote&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;New&lt;/span&gt; &lt;span class="nx"&gt;Note&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/header&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;aside&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;list&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/aside&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hidden&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Title&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;textarea&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Write your note here&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/textarea&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;editor-actions&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tags&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tags separated by commas&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;save&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Save&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;delete&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Delete&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Close&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/section&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/main&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;script.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/body&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/html&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Navigation Bar (header): Contains the app title, a search box, and a button to create new notes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Notes List Panel (aside): Displays all saved notes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Editor Panel (section): Provides fields for writing, tagging, saving, or deleting notes. Hidden by default until a note is opened or created.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 2: Add CSS Styling
&lt;/h2&gt;

&lt;p&gt;Now that we have written the  HTML codes for the project, we can now write the CSS codes for the project that would be responsible for the beautification and positioning of the elements in the project.&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;style.css file&lt;/code&gt; and add the following codes.&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;html&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="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;system&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Arial&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Helvetica&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;header&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;justify&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;space&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;between&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;align&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;border&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt; &lt;span class="nx"&gt;solid&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;ddd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;controls&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;220&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;main&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;aside&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;320&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;border&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt; &lt;span class="nx"&gt;solid&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;eee&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;auto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;border&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt; &lt;span class="nx"&gt;solid&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;f0f0f0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="mi"&gt;666&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;border&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;section&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hidden&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;textarea&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;sizing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;border&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;box&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="nx"&gt;vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;align&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;tag&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;inline&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;margin&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;border&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="nx"&gt;px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;f3f3f3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;font&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="nx"&gt;px&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;ul&gt;
&lt;li&gt;&lt;p&gt;Header Styling: Creates a top navigation bar with search and button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sidebar Styling: Sets width and scroll behavior for the notes list.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Editor Styling: Expands the editor panel and makes it flexible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Note Item Styling: Adds borders, spacing, and hover-friendly design.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Responsive Layout: Flexbox ensures panels resize correctly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Add JavaScript Functionality
&lt;/h2&gt;

&lt;p&gt;After we have written the CSS codes for the beautification of the project, we can now write the javaScript code to make the project interactive and functional. &lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;script.js file&lt;/code&gt; and add the following codes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setup and Local Storage (Initialization):&lt;/strong&gt; This aspect of the code handles data persistence, making sure notes survive page reloads.&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;storageKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;notes-v1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;activeId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;

&lt;span class="c1"&gt;// Shortcut for selecting elements&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Save notes to local storage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saveToStorage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;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="nx"&gt;storageKey&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;notes&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Load notes from local storage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadFromStorage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;raw&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="nx"&gt;storageKey&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;raw&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;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="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;raw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Rendering and Displaying Notes:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This aspect of the code ensures users can see and search through their notes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Format timestamp into a readable string&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ts&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;d&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;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ts&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;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Render list of notes in the sidebar&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;renderList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filter&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;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;el&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;

  &lt;span class="c1"&gt;// Filter and sort notes&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="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;filter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&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;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[]).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="c1"&gt;// Show message if no notes found&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;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No notes found&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&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="c1"&gt;// Render each note as a card in the list&lt;/span&gt;
  &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;note-item&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Untitled&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;h&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;meta&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;meta&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;formatDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;// Add tags (if any)&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;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tagWrap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;div&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&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;tspan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nx"&gt;tspan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;className&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-note-tag&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="nx"&gt;tspan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;
        &lt;span class="nx"&gt;tagWrap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tspan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tagWrap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Click event to open note in editor&lt;/span&gt;
    &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;openEditor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Editor Functions (Open, Close, Create, Save, Delete):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This aspect of the code provides the core functionality of the app, that is for the user to be able to create, read, update, and  delete notes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Open editor for a specific note&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;openEditor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;id&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;activeId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;editor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hidden&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
  &lt;span class="nf"&gt;el&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
  &lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;[]).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Close editor and reset inputs&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;closeEditor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;activeId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
  &lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;editor&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;classList&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="s1"&gt;hidden&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
  &lt;span class="nf"&gt;el&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
  &lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Create a new note&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createNote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;n_&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="na"&gt;created&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;updated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;saveToStorage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;renderList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;search&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;openEditor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Save current note&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;saveNote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="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;activeId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;activeId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;note&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;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;el&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;saveToStorage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;renderList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;search&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;closeEditor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Delete current note&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deleteNote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="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;activeId&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;notes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;notes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;activeId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;saveToStorage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;renderList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;search&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;closeEditor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Event Binding and App Initialization:&lt;/strong&gt;&lt;br&gt;
 This aspect of the code handles user interactions and the application startup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Bind user events&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bind&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;newNote&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;createNote&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;save&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;saveNote&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;delete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;deleteNote&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;closeEditor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;el&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;search&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;renderList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

  &lt;span class="c1"&gt;// Keyboard shortcut: Ctrl + N creates a new note&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctrlKey&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="nf"&gt;createNote&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Initialize app&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;init&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;loadFromStorage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nf"&gt;renderList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;User Interface Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The user interface shows what the user will see when the user wants to use the product. The user will see Navigation Bar that includes title, search bar, and New Note button. A Notes List Panel that displays all saved notes. An Editor Panel that includes Text area with title, tags, and action buttons. Search and Filter that can filter notes by keywords or tags.&lt;br&gt;
This is the exact image the user will see.&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%2Fer8puvsz01b70rvj5yz0.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%2Fer8puvsz01b70rvj5yz0.PNG" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Future Enhancements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Possible future enhancements that can be added to the project includes the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Cloud sync across devices&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;User authentication and login&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rich text editing with formatting options&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;This tutorial showed how to build a complete note-taking app with HTML, CSS, and JavaScript. You learned how to manage data with local storage, render a dynamic interface, and handle user interactions. This is a foundation you can extend with more advanced features like categories, cloud sync, or authentication.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>learning</category>
      <category>software</category>
    </item>
    <item>
      <title>Understanding Object-Oriented Programming (OOP) in JavaScript</title>
      <dc:creator>henry messiah tmt</dc:creator>
      <pubDate>Sat, 13 Sep 2025 10:29:14 +0000</pubDate>
      <link>https://dev.to/henry_messiahtmt_099ca84/understanding-object-oriented-programming-oop-in-javascript-3cf8</link>
      <guid>https://dev.to/henry_messiahtmt_099ca84/understanding-object-oriented-programming-oop-in-javascript-3cf8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Programming is much like building a city. You don’t throw bricks, cement, and metal randomly together, instead you carefully organize them into structures like houses, schools, and hospitals. In the same way, coding requires structure and organization to make programs easy to build, extend, and maintain.&lt;/p&gt;

&lt;p&gt;This is where Object-Oriented Programming (OOP) comes in. OOP is a programming paradigm that allows developers to model real-world entities as objects with properties (data) and behaviors (functions). In JavaScript, OOP is extremely powerful because it makes your code reusable, scalable, and easier to understand.&lt;/p&gt;

&lt;p&gt;Understanding OOP in JavaScript is important because it gives you the foundation to work on complex projects, collaborate with teams, and write clean, modular code that mirrors real-life situations. &lt;/p&gt;

&lt;p&gt;In this tutorial, we aim to simplify the concept of Object-Oriented Programming (OOP) and make it easy to understand for learners at all levels. By the end of this guide, readers will not only grasp the fundamental principles of OOP but will also be able to confidently apply them in building both simple and complex projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Object-Oriented Programming (OOP)?
&lt;/h2&gt;

&lt;p&gt;Object-Oriented Programming (OOP) is a way of writing code where you structure it around objects. An object is a collection of properties (attributes) and methods (functions) that describe and control a specific thing.&lt;br&gt;
JavaScript, unlike some traditional OOP languages like Java or C++, is prototype-based, but with the introduction of ES6, we now have the class syntax that makes OOP in JavaScript more familiar and readable.&lt;/p&gt;
&lt;h2&gt;
  
  
  Core Principles of OOP in JavaScript
&lt;/h2&gt;

&lt;p&gt;There are four main pillars of OOP. Let’s break them down:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Encapsulation:&lt;/strong&gt; Bundling related data and methods together inside a single object while restricting direct access to certain parts.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Abstraction:&lt;/strong&gt; Hiding complex details and exposing only the essentials.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inheritance:&lt;/strong&gt; Allowing one class (child) to acquire properties and methods of another (parent).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Polymorphism:&lt;/strong&gt; The ability for the same method or function to behave differently depending on the context.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Real-World Analogy of OOP
&lt;/h2&gt;

&lt;p&gt;Imagine you’re designing a Car System:&lt;br&gt;
• &lt;strong&gt;Encapsulation:&lt;/strong&gt; The car has properties like color, brand, and engineType, and methods like startEngine() or applyBrakes(). You don’t directly control how the engine works internally, you just start it.&lt;br&gt;
• &lt;strong&gt;Abstraction:&lt;/strong&gt; You turn the steering wheel to change direction but you don’t need to know the complex physics behind it.&lt;br&gt;
• &lt;strong&gt;Inheritance:&lt;/strong&gt; A SportsCar can inherit features of a general Car but have additional features like turboBoost().&lt;br&gt;
• &lt;strong&gt;Polymorphism:&lt;/strong&gt; The method drive() can mean different things depending on whether it’s a Car, a Bike, or a Truck.&lt;br&gt;
This structure makes the car system easier to understand, expand, and maintain. The same applies to code.&lt;/p&gt;
&lt;h2&gt;
  
  
  OOP in JavaScript with Examples
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Encapsulation (Creating a Class)&lt;/strong&gt;
Encapsulation means bundling data (properties) and methods (functions) into one unit (class).
&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="c1"&gt;// Encapsulation example with a Car class&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// The constructor is used to initialize object properties&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;brand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// property to store the car brand&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// property to store the car color&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Method to start the car engine&lt;/span&gt;
  &lt;span class="nf"&gt;startEngine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Access the car's brand property&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; engine started!`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Create a new object (instance) of the Car class&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myCar&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;Car&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Toyota&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;Red&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Call the method to start the engine&lt;/span&gt;
&lt;span class="nx"&gt;myCar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startEngine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Output: Toyota engine started!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;2. Abstraction&lt;/strong&gt;&lt;br&gt;
Abstraction hides unnecessary details and exposes only the essential methods.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Abstraction example with a BankAccount class&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BankAccount&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// account owner's name&lt;/span&gt;

    &lt;span class="c1"&gt;// Private variable to hold the balance&lt;/span&gt;
    &lt;span class="c1"&gt;// It cannot be accessed directly outside the class&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;_balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Method to check current balance (controlled access)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getBalance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;_balance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// Method to deposit money (changes balance internally)&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;deposit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;_balance&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Deposited &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;. New balance: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;_balance&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Create a new bank account with an initial balance of 1000&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;account&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;BankAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Peace&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Deposit money using the provided method&lt;/span&gt;
&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: Deposited 500. New balance: 1500&lt;/span&gt;

&lt;span class="c1"&gt;// Access the balance safely through the method&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;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Output: 1500&lt;/span&gt;

&lt;span class="c1"&gt;// Direct access like account._balance is not possible (hidden!)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Inheritance&lt;/strong&gt;&lt;br&gt;
Inheritance allows one class to acquire the properties and methods of another.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Parent class Vehicle&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// type of vehicle (e.g., Car, Bike, Truck)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Method for movement&lt;/span&gt;
  &lt;span class="nf"&gt;move&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is moving...`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Child class Bike extends Vehicle&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Bike&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// super() calls the parent class constructor&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;brand&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// brand of the bike&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Override the parent move() method with custom behavior&lt;/span&gt;
  &lt;span class="nf"&gt;move&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is speeding away!`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Create an instance of Bike&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myBike&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;Bike&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Motorbike&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;Yamaha&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Call the overridden method&lt;/span&gt;
&lt;span class="nx"&gt;myBike&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Output: Yamaha Motorbike is speeding away!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Polymorphism&lt;/strong&gt;&lt;br&gt;
Polymorphism allows the same method name to behave differently depending on the object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Parent class Animal&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Default method for speaking&lt;/span&gt;
  &lt;span class="nf"&gt;speak&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;This animal makes a sound.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Child class Dog overrides speak()&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;speak&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;Woof! Woof!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Child class Cat overrides speak()&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;speak&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;Meow!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Create an array of different animals&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;animals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Animal&lt;/span&gt;&lt;span class="p"&gt;()];&lt;/span&gt;

&lt;span class="c1"&gt;// Each object responds differently to the same method call&lt;/span&gt;
&lt;span class="nx"&gt;animals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;animal&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;animal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;speak&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="cm"&gt;/* Output:
Woof! Woof!
Meow!
This animal makes a sound.
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Importance Of OOP Matters in JavaScript
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Code Reusability&lt;/strong&gt;&lt;br&gt;
• With OOP, you can create reusable classes or objects that can be used across different parts of your application.&lt;br&gt;
• Example: A User class with login/logout methods can be reused in multiple projects.&lt;br&gt;
&lt;strong&gt;2. Modularity (Better Organization)&lt;/strong&gt;&lt;br&gt;
• OOP helps break down complex code into smaller, manageable pieces (classes/objects).&lt;br&gt;
• Each object focuses on one specific task, making the codebase easier to navigate and maintain.&lt;br&gt;
&lt;strong&gt;3. Encapsulation (Data Hiding &amp;amp; Security)&lt;/strong&gt;&lt;br&gt;
• OOP allows you to hide the internal implementation of an object and expose only what’s necessary.&lt;br&gt;
• Example: Instead of directly changing a bank account’s balance, you might only allow deposits/withdrawals through specific methods.&lt;br&gt;
&lt;strong&gt;4. Inheritance (Avoiding Duplication)&lt;/strong&gt;&lt;br&gt;
• You can create a parent class with common properties and methods, and let child classes inherit them.&lt;br&gt;
• This reduces duplication of code and enforces consistency.&lt;br&gt;
• Example: A Vehicle class → extended by Car, Bike, Bus.&lt;br&gt;
&lt;strong&gt;5. Polymorphism (Flexibility &amp;amp; Extensibility)&lt;/strong&gt;&lt;br&gt;
• Objects can share the same interface but behave differently based on the context.&lt;br&gt;
• Example: A draw() method might render a circle, square, or triangle differently depending on the object.&lt;br&gt;
&lt;strong&gt;6. Improved Maintainability&lt;/strong&gt;&lt;br&gt;
• Since OOP structures your code in clear, self-contained objects, it becomes easier to fix bugs, add features, or make changes without breaking other parts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Scalability (Good for Large Applications)&lt;/strong&gt;&lt;br&gt;
• Large projects (like web apps, games, and enterprise software) benefit from OOP because it makes it easier to manage growing codebases.&lt;br&gt;
&lt;strong&gt;8. Real-World Modeling&lt;/strong&gt;&lt;br&gt;
• OOP mirrors real-world entities (users, products, orders, etc.), making the design more intuitive.&lt;br&gt;
• Example: In an e-commerce app, you can have classes for Product, Cart, and Order that closely resemble real-world objects.&lt;/p&gt;

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

&lt;p&gt;Object-Oriented Programming (OOP) in JavaScript is not just a concept — it’s a powerful way to think about code. By understanding encapsulation, abstraction, inheritance, and polymorphism, you can write cleaner, smarter, and more professional programs.&lt;br&gt;
 OOP is  like building blocks — once you master them, you can create applications as small as a calculator or as big as a social media platform.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Understanding Encapsulation in JavaScript</title>
      <dc:creator>henry messiah tmt</dc:creator>
      <pubDate>Thu, 04 Sep 2025 02:44:51 +0000</pubDate>
      <link>https://dev.to/henry_messiahtmt_099ca84/understanding-encapsulation-in-javascript-29d3</link>
      <guid>https://dev.to/henry_messiahtmt_099ca84/understanding-encapsulation-in-javascript-29d3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Have you ever wondered why an ATM never shows you its inner workings, yet always gives you just the right amount of money when you press a button? Or why your favorite apps protect your passwords without ever exposing them? Behind these everyday experiences lies a powerful programming principle called Encapsulation.&lt;/p&gt;

&lt;p&gt;In JavaScript, encapsulation is the art of hiding the messy details of how something works and exposing only what you need to use. It’s like driving a car, you don’t have to know how the engine combusts fuel, you just press the accelerator and the car moves. Encapsulation makes our code safer, cleaner, and easier to work with, while giving us full control over how data is accessed and modified.&lt;/p&gt;

&lt;p&gt;Documenting encapsulation is important because it helps developers understand how to properly structure applications, protect data, and avoid coding mistakes that lead to bugs and security flaws. With the guide from this documentation, you and your team can build reliable software that scales well and remains easy to maintain.&lt;/p&gt;

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

&lt;p&gt;Encapsulation in JavaScript is one of the core principles of Object-Oriented Programming (OOP).&lt;/p&gt;

&lt;p&gt;It means bundling related data (properties/variables) and behavior (methods/functions) into a single unit (object or class) while restricting direct access to some parts of that object.&lt;/p&gt;

&lt;p&gt;Encapsulation in simple terms means keeping data and methods together in one unit while restricting direct access to some details. You show only what is needed. You hide the rest.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Use Encapsulation?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Protects data from unsafe changes.&lt;/li&gt;
&lt;li&gt;Gives controlled access through getters and setters.&lt;/li&gt;
&lt;li&gt;Keeps code organized and reusable.&lt;/li&gt;
&lt;li&gt;Provides better security for sensitive logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Examples of encapsulation in JavaScript
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;Using Objects&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="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;Henry&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;36&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="nf"&gt;getAge&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="nf"&gt;setAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newAge&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newAge&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newAge&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="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;Invalid age&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAge&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 36&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;setAge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAge&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 40&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, age is managed only through getAge and setAge.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;Using Classes with Private Fields&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BankAccount&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="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;Insufficient funds&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;account&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;BankAccount&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;300&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;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 700&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The field #balance is private and cannot be accessed from outside.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Using Closures&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;engineOn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;startEngine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;engineOn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;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;Engine started&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;stopEngine&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;engineOn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;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;Engine stopped&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;drive&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;engineOn&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;Car is moving&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;else&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;Start the engine first&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myCar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;myCar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drive&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;       &lt;span class="c1"&gt;// Start the engine first&lt;/span&gt;
&lt;span class="nx"&gt;myCar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startEngine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Engine started&lt;/span&gt;
&lt;span class="nx"&gt;myCar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drive&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;       &lt;span class="c1"&gt;// Car is moving&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The variable engineOn is private to the function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real World Examples
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;ATM Machine&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;class&lt;/span&gt; &lt;span class="nc"&gt;ATM&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialBalance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialBalance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Deposited: ₦&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Withdrawn: ₦&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&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;Insufficient funds&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myATM&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;ATM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;myATM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deposit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;myATM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;withdraw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;300&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;Balance:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;myATM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getBalance&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 1200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The balance is private. You only interact through deposit, withdraw, and getBalance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Password Manager&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;PasswordManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;passwords&lt;/span&gt; &lt;span class="o"&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="na"&gt;addPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;site&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pwd&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;passwords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;site&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;pwd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;getPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;site&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;passwords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;site&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;****&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No password 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;span class="na"&gt;verifyPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;site&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pwd&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;passwords&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;site&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;pwd&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;manager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PasswordManager&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;manager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gmail&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;mySecret123&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;manager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gmail&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&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;manager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verifyPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gmail&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;mySecret123&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The stored passwords are hidden and safe from direct access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Car&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;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;engineStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;startEngine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;engineStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;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;Engine started&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;stopEngine&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;engineStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;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;Engine stopped&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;drive&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;engineStatus&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;Car is moving&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;else&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;Start the engine first&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myCar&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;Car&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;myCar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drive&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;       
&lt;span class="nx"&gt;myCar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startEngine&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
&lt;span class="nx"&gt;myCar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;drive&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;       
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The engine status is hidden. The driver interacts only with exposed methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Encapsulation means hiding internal details.&lt;/p&gt;

&lt;p&gt;It gives controlled access through methods.&lt;/p&gt;

&lt;p&gt;It keeps data safe and code maintainable.&lt;/p&gt;

&lt;p&gt;Real-world parallels include ATMs, password managers, and cars.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>learning</category>
    </item>
    <item>
      <title>Understanding Polymorphism in JavaScript</title>
      <dc:creator>henry messiah tmt</dc:creator>
      <pubDate>Fri, 29 Aug 2025 00:59:57 +0000</pubDate>
      <link>https://dev.to/henry_messiahtmt_099ca84/understanding-polymorphism-in-javascript-i7n</link>
      <guid>https://dev.to/henry_messiahtmt_099ca84/understanding-polymorphism-in-javascript-i7n</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Polymorphism is one of the hardest concepts for new programmers to understand. The word itself looks complex and can confuse beginners. Many learners struggle because the explanations they find are filled with theory and technical terms. This makes the topic feel harder than it is.&lt;/p&gt;

&lt;p&gt;The aim of this document is to explain polymorphism in simple terms. You will see how it works through clear examples from everyday life. The goal is to help you understand what polymorphism means and how you can apply it in JavaScript. Real life comparisons, like a house lamp, phone charger, vehicles, and remote control, will make the concept practical and easy to remember.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Polymorphism
&lt;/h2&gt;

&lt;p&gt;Polymorphism means one name with many forms. A single method or function behaves differently depending on the object or context. This is part of object-oriented programming.&lt;/p&gt;

&lt;p&gt;Example: House Lamp&lt;br&gt;
You buy one lamp for your house. You use it in the room, parlor, and kitchen. The same lamp behaves differently in each location.&lt;/p&gt;

&lt;p&gt;JavaScript 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="nf"&gt;turnOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;room&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lamp gives soft light in the room.&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;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parlor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lamp gives bright light in the parlor.&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;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kitchen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lamp gives white light in the kitchen.&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;else&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;Lamp gives default light.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lamp&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;HouseLamp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;lamp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;turnOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;room&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;lamp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;turnOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parlor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;lamp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;turnOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kitchen&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;### Other Examples&lt;/p&gt;

&lt;h3&gt;
  
  
  Phone Charger
&lt;/h3&gt;

&lt;p&gt;One charger works for different devices.&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;class&lt;/span&gt; &lt;span class="nc"&gt;Charger&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;device&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="s2"&gt;`Charging &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;device&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;charger&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;Charger&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;charger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;phone&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;charger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tablet&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;charger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;power bank&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;Vehicles&lt;/span&gt;
&lt;span class="nx"&gt;All&lt;/span&gt; &lt;span class="nx"&gt;vehicles&lt;/span&gt; &lt;span class="nx"&gt;move&lt;/span&gt; &lt;span class="nx"&gt;but&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;its&lt;/span&gt; &lt;span class="nx"&gt;own&lt;/span&gt; &lt;span class="nx"&gt;way&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;move&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;This vehicle moves.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;move&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;The car drives.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Boat&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;move&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;The boat sails.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Plane&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;move&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;The plane flies.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;vehicles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Car&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Boat&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Plane&lt;/span&gt;&lt;span class="p"&gt;()];&lt;/span&gt;
&lt;span class="nx"&gt;vehicles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Remote Control
&lt;/h4&gt;

&lt;p&gt;One remote operates different devices.&lt;/p&gt;

&lt;p&gt;Switch on TV,&lt;/p&gt;

&lt;p&gt;Play music on speaker,&lt;/p&gt;

&lt;p&gt;Control a fan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Polymorphism Matters?
&lt;/h3&gt;

&lt;p&gt;Reuse methods in different contexts,&lt;/p&gt;

&lt;p&gt;Keep your code flexible,&lt;/p&gt;

&lt;p&gt;Make updates easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discriminator Properties in Polymorphism
&lt;/h2&gt;

&lt;p&gt;In JavaScript, polymorphism often needs a way to decide how a method should behave. This is where discriminator properties help. A discriminator property is a special value inside an object that tells the program which form of behavior to use.&lt;/p&gt;

&lt;p&gt;Think of it as a label. The label helps the program pick the right action.&lt;/p&gt;

&lt;p&gt;Example with House Lamp&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;class&lt;/span&gt; &lt;span class="nc"&gt;HouseLamp&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// discriminator property&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;turnOn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;room&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lamp gives soft light in the room.&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;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parlor&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lamp gives bright light in the parlor.&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;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kitchen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Lamp gives white light in the kitchen.&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;else&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;Lamp gives default light.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;roomLamp&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;HouseLamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;room&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;parlorLamp&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;HouseLamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;parlor&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;kitchenLamp&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;HouseLamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;kitchen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;roomLamp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;turnOn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;parlorLamp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;turnOn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;kitchenLamp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;turnOn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the property location is the discriminator. It changes how the method turnOn behaves.&lt;/p&gt;

&lt;p&gt;Example with Vehicles&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;class&lt;/span&gt; &lt;span class="nc"&gt;Vehicle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// discriminator property&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;car&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The car drives.&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;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;boat&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The boat sails.&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;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plane&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The plane flies.&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;else&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;Unknown vehicle type.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;car&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;Vehicle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;car&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;boat&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;Vehicle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;boat&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;plane&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;Vehicle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plane&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;car&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;boat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;plane&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;move&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the property type acts as the discriminator. It decides how the vehicle moves.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Discriminator Properties Help?
&lt;/h3&gt;

&lt;p&gt;They give objects a clear identity,&lt;br&gt;
They make code easier to extend,&lt;br&gt;
Add a new type, define its behavior, and the same method works.&lt;br&gt;
They keep your methods reusable but context-aware.&lt;/p&gt;

&lt;h2&gt;
  
  
  conclusions
&lt;/h2&gt;

&lt;p&gt;Polymorphism lets you use one function or method name in many forms. The context decides the behavior.&lt;/p&gt;

&lt;p&gt;A discriminator property is like a switch inside an object. It tells the method how to behave. This makes polymorphism more practical and easier to control in real projects.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>javascript</category>
      <category>programming</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
