<?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: Sreeharsha</title>
    <description>The latest articles on DEV Community by Sreeharsha (@sraveend).</description>
    <link>https://dev.to/sraveend</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%2F1081410%2F2a637dd0-6212-4d5c-a187-bb9ad0e0e9d4.jpeg</url>
      <title>DEV Community: Sreeharsha</title>
      <link>https://dev.to/sraveend</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sraveend"/>
    <language>en</language>
    <item>
      <title>Shipping a MCP Server alongside your API</title>
      <dc:creator>Sreeharsha</dc:creator>
      <pubDate>Wed, 25 Feb 2026 06:00:45 +0000</pubDate>
      <link>https://dev.to/sraveend/shipping-a-mcp-server-alongside-your-api-48d7</link>
      <guid>https://dev.to/sraveend/shipping-a-mcp-server-alongside-your-api-48d7</guid>
      <description>&lt;h2&gt;
  
  
  TLDR;
&lt;/h2&gt;

&lt;p&gt;MCP tools and REST APIs serve fundamentally different consumers — humans navigate discovery, agents need curated capabilities. &lt;/p&gt;

&lt;p&gt;Instead of deploying a separate MCP service or auto-converting your existing API, you can mount an MCP server directly alongside your FastAPI application using FastMCP 3.x. &lt;/p&gt;

&lt;p&gt;Both interfaces share the same services, database, and authentication, but each is designed for its own consumer. &lt;/p&gt;

&lt;p&gt;This article covers the design philosophy, architecture, and engineering challenges of shipping this dual-interface pattern.&lt;/p&gt;




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

&lt;p&gt;&lt;a href="https://modelcontextprotocol.io/docs/getting-started/intro" rel="noopener noreferrer"&gt;MCP (Model Context Protocol)&lt;/a&gt; is an open standard that defines how AI systems interact with external tools, data sources, and applications. Rather than building bespoke integrations for each model-service pair, MCP provides a single protocol that any AI agent can speak.&lt;/p&gt;

&lt;p&gt;An MCP server exposes three types of capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tools&lt;/strong&gt; — Functions the LLM calls autonomously to take action. The model decides when and how to invoke them based on conversation context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources&lt;/strong&gt; — Structured data the application provides as context. These are read-only and addressed via URIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompts&lt;/strong&gt; — Pre-built templates that guide users through structured workflows with validated inputs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Of these, &lt;strong&gt;tools&lt;/strong&gt; are the primary interface for agentic workflows — and they're where the design challenge lives.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployment
&lt;/h3&gt;

&lt;p&gt;When teams adopt MCP, the default instinct is to deploy the MCP server as a &lt;strong&gt;separate service&lt;/strong&gt; alongside the existing API. This mirrors the microservices pattern: independent scaling, isolated failure domains.&lt;/p&gt;

&lt;p&gt;But for most applications, the MCP tools and REST endpoints operate on the &lt;strong&gt;same data&lt;/strong&gt;, apply the &lt;strong&gt;same business rules&lt;/strong&gt;, and authenticate the &lt;strong&gt;same users&lt;/strong&gt;. A separate service means duplicated logic, duplicated auth configuration, and additional infrastructure — all for a protocol adapter.&lt;/p&gt;

&lt;p&gt;The alternative — and the pattern this article explores — is mounting the MCP server &lt;strong&gt;as a sub-application inside your existing API server&lt;/strong&gt;. FastMCP 3.x generates a standard ASGI application, which means it slots natively into FastAPI or Starlette with a single &lt;code&gt;mount()&lt;/code&gt; call.&lt;/p&gt;

&lt;p&gt;The result:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Consumer&lt;/th&gt;
&lt;th&gt;Interface&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/api/*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Web/mobile clients, curl&lt;/td&gt;
&lt;td&gt;REST (FastAPI)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/mcp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;AI agents, LLM clients&lt;/td&gt;
&lt;td&gt;MCP (FastMCP)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/health&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Infrastructure&lt;/td&gt;
&lt;td&gt;HTTP GET&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One deployment. One database. One authentication secret. Two interfaces, each designed for its consumer.&lt;/p&gt;

&lt;h3&gt;
  
  
  When This Pattern Fits
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Good fit:&lt;/strong&gt; Your MCP tools and API endpoints serve the same domain with the same data. You want fast time-to-market without new infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Less ideal:&lt;/strong&gt; You need independent scaling for heavy MCP traffic, or your MCP tools integrate data sources that your API doesn't touch.&lt;/p&gt;




&lt;h2&gt;
  
  
  Design
&lt;/h2&gt;

&lt;h3&gt;
  
  
  REST APIs Are Not MCP Tools
&lt;/h3&gt;

&lt;p&gt;The fundamental insight, &lt;a href="https://www.jlowin.dev/blog/stop-converting-rest-apis-to-mcp" rel="noopener noreferrer"&gt;articulated well by Jlowin&lt;/a&gt; (FastMCP's creator), is that REST APIs and MCP tools are designed for consumers with opposite needs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;REST APIs are designed for human developers.&lt;/strong&gt; They optimize for discoverability and atomicity. Hundreds of single-purpose endpoints are a feature, because human developers do discovery once, write code that chains atomic calls together, and iterate cheaply. More choice is good.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP tools are designed for LLM agents.&lt;/strong&gt; Every tool an LLM has access to is processed in its context window on every reasoning step — every name, description, and parameter schema. More tools means more tokens, more latency, and more opportunities for the model to make wrong choices. Atomicity is an antipattern: each tool call triggers a full reasoning cycle that costs time and money.&lt;/p&gt;

&lt;p&gt;This creates a concrete design mismatch:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;REST API&lt;/th&gt;
&lt;th&gt;MCP Tool&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Audience&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Human developer writing code&lt;/td&gt;
&lt;td&gt;LLM agent reasoning in context&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Cost of choice&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cheap — ignored at compile time&lt;/td&gt;
&lt;td&gt;Expensive — processed every inference&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Iteration cost&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Fast — network hops are milliseconds&lt;/td&gt;
&lt;td&gt;Slow — each call is a full reasoning cycle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Design ideal&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Rich, composable, atomic&lt;/td&gt;
&lt;td&gt;Ruthlessly curated, minimal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Failure mode&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;404 / 500 errors&lt;/td&gt;
&lt;td&gt;Hallucinated tools, wrong tool selection&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Designing Tools from Agent Stories
&lt;/h3&gt;

&lt;p&gt;The right approach is to start not from your API spec, but from the &lt;strong&gt;agent story&lt;/strong&gt;: &lt;em&gt;"As an agent, given {context}, I use {tools} to achieve {outcome}."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For a todos application, the agent story is simple: &lt;em&gt;"As an agent, given an authenticated user, I use todo management tools to help the user create, view, update, and complete tasks."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This leads to &lt;strong&gt;five curated tools&lt;/strong&gt; — not nine REST endpoints:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;MCP Tool&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Why it exists&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_all_todos&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Overview of all tasks&lt;/td&gt;
&lt;td&gt;Agent needs full picture to reason about priorities&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_todo_by_id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inspect a specific task&lt;/td&gt;
&lt;td&gt;Agent needs current state before suggesting updates&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;create_todo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a task&lt;/td&gt;
&lt;td&gt;Core capability for task management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;update_todo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Modify a task&lt;/td&gt;
&lt;td&gt;Includes completion — no separate "mark done" endpoint&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;delete_todo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Remove a task&lt;/td&gt;
&lt;td&gt;Destructive — tool description tells agent to confirm first&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each tool gets a &lt;strong&gt;rich description&lt;/strong&gt; that instructs the LLM on when and how to use it. For example, &lt;code&gt;update_todo&lt;/code&gt;'s description states: &lt;em&gt;"All fields are required — provide current values for fields you do not want to change. Use get_todo_by_id first to fetch the current values before updating."&lt;/em&gt; This kind of guidance is meaningless in REST but critical for MCP.&lt;/p&gt;




&lt;h2&gt;
  
  
  Implementation Overview
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/sreeharsha-rav/python-apps/tree/main/learn-fastmcp/todos" rel="noopener noreferrer"&gt;github: &lt;strong&gt;todos&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The application follows a layered architecture where the services and data access layers are shared, and only the interface layer differs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────┐    ┌──────────────────────┐
│   REST API (api.py)  │    │  MCP Tools (mcp.py)  │
│   9 endpoints        │    │   5 tools            │
│   FastAPI Depends()  │    │   FastMCP Depends()  │
└──────────┬───────────┘    └──────────┬───────────┘
           │                           │
           └─────────┬─────────────────┘
                     ▼
           ┌─────────────────────┐
           │   Services Layer    │
           │ AuthService          │
           │ TodoService          │
           └─────────┬───────────┘
                     ▼
           ┌─────────────────────┐
           │  Repository Layer   │
           │ UserRepository       │
           │ TodoRepository       │
           └─────────┬───────────┘
                     ▼
           ┌─────────────────────┐
           │   SQLAlchemy/SQLite │
           └─────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How It Comes Together
&lt;/h3&gt;

&lt;p&gt;The root application (&lt;code&gt;main.py&lt;/code&gt;) composes everything:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Creates the MCP ASGI app&lt;/strong&gt; from the FastMCP server instance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Combines lifespans&lt;/strong&gt; — database table initialization and MCP session management are merged using &lt;code&gt;combine_lifespans()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Applies middleware at root level&lt;/strong&gt; — CORS (including MCP-specific headers like &lt;code&gt;mcp-session-id&lt;/code&gt;) and request logging apply uniformly to all sub-apps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Registers OAuth discovery routes&lt;/strong&gt; at the root (these must live outside the &lt;code&gt;/mcp&lt;/code&gt; prefix)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mounts both interfaces&lt;/strong&gt; — REST API at &lt;code&gt;/api&lt;/code&gt;, MCP server at &lt;code&gt;/mcp&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Shared Authentication
&lt;/h3&gt;

&lt;p&gt;The REST API issues JWTs at &lt;code&gt;/api/auth/token&lt;/code&gt;. The MCP server validates those same tokens using FastMCP's &lt;code&gt;JWTVerifier&lt;/code&gt;, configured with the same HS256 secret. Users authenticate once through the REST API and can use the token with either interface.&lt;/p&gt;

&lt;p&gt;Inside MCP tools, user identity is extracted from the verified token claims — the same &lt;code&gt;sub&lt;/code&gt; claim that the REST API reads, resolving to the same user record in the same database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shared Business Logic
&lt;/h3&gt;

&lt;p&gt;Both interfaces resolve to the same &lt;code&gt;AuthService&lt;/code&gt; and &lt;code&gt;TodoService&lt;/code&gt; classes. The service and repository layers are written once and used by both. Only the dependency injection wiring differs between the two frameworks (see Challenges below).&lt;/p&gt;




&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. OAuth Discovery Routes Must Live at Root
&lt;/h3&gt;

&lt;p&gt;MCP clients authenticate via Streamable HTTP and expect OAuth discovery endpoints at well-known paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /.well-known/oauth-protected-resource/mcp
GET /.well-known/oauth-authorization-server/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These &lt;strong&gt;cannot&lt;/strong&gt; be nested under the &lt;code&gt;/mcp&lt;/code&gt; mount prefix — they must be registered on the root application. Missing these routes caused silent authentication failures that were difficult to diagnose. FastMCP provides &lt;code&gt;mcp.auth.get_well_known_routes()&lt;/code&gt; to generate these routes, but you must explicitly append them to the root app.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Middleware Configuration at Root
&lt;/h3&gt;

&lt;p&gt;The initial implementation had &lt;strong&gt;separate middleware&lt;/strong&gt; for both the FastAPI and FastMCP sub-applications. This caused CORS issues — the MCP protocol uses custom headers (&lt;code&gt;mcp-protocol-version&lt;/code&gt;, &lt;code&gt;mcp-session-id&lt;/code&gt;) that need to be allowed and exposed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_middleware&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;CORSMiddleware&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;allow_headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mcp-protocol-version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mcp-session-id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;expose_headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mcp-session-id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Moving CORS and logging middleware to the &lt;strong&gt;root-level&lt;/strong&gt; app (so it applies to all sub-apps uniformly) resolved the issue. This is also the approach recommended by FastMCP's documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Dependency Injection — Two Systems, One Service Layer
&lt;/h3&gt;

&lt;p&gt;FastAPI and FastMCP each provide their own &lt;code&gt;Depends()&lt;/code&gt; function, and they are &lt;strong&gt;not interchangeable&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FastAPI's &lt;code&gt;Depends&lt;/code&gt;&lt;/strong&gt; uses generator-based resolution (&lt;code&gt;yield&lt;/code&gt; in a generator function)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FastMCP's &lt;code&gt;Depends&lt;/code&gt;&lt;/strong&gt; uses its own resolver that expects a &lt;code&gt;@contextmanager&lt;/code&gt; decorated function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using FastAPI's DI in FastMCP tools caused resolution errors like &lt;code&gt;Failed to resolve dependency 'user'&lt;/code&gt;. The fix was defining &lt;strong&gt;separate dependency providers&lt;/strong&gt; in &lt;code&gt;mcp.py&lt;/code&gt; using &lt;code&gt;fastmcp.dependencies.Depends&lt;/code&gt; and &lt;code&gt;@contextmanager&lt;/code&gt; for DB sessions, while keeping the FastAPI providers in &lt;code&gt;services/__init__.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Both resolve to the same &lt;code&gt;AuthService&lt;/code&gt; and &lt;code&gt;TodoService&lt;/code&gt; classes — the dependency &lt;em&gt;wiring&lt;/em&gt; is separate, but the &lt;em&gt;business logic&lt;/em&gt; is fully shared.&lt;/p&gt;




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

&lt;p&gt;The dual-interface pattern — a REST API and MCP server sharing a single deployment — is a pragmatic choice for teams adding agent capabilities to an existing backend. You avoid duplicating business logic, authentication, and infrastructure. You ship one container instead of two.&lt;/p&gt;

&lt;p&gt;But the design lesson runs deeper than deployment topology. REST APIs and MCP tools serve fundamentally different consumers. The endpoints that make your API discoverable and composable for human developers can drown an LLM in context. The right approach is to &lt;strong&gt;curate your MCP tools independently&lt;/strong&gt; — start from the agent's story, not from your OpenAPI spec.&lt;/p&gt;

&lt;p&gt;The code reuse happens at the service layer, not the interface layer. That's the key architectural insight: share the logic, design the surfaces separately.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The official MCP guide to &lt;a href="https://modelcontextprotocol.io/docs/develop/build-server" rel="noopener noreferrer"&gt;building a server&lt;/a&gt; references &lt;code&gt;from mcp.server.fastmcp import FastMCP&lt;/code&gt; (the low-level SDK). As of February 2026, &lt;a href="https://github.com/PrefectHQ/fastmcp/tree/main" rel="noopener noreferrer"&gt;FastMCP v3&lt;/a&gt; (&lt;code&gt;from fastmcp import FastMCP&lt;/code&gt;) is the recommended high-level framework, offering Streamable HTTP, ASGI integration, web framework mounting, and a CLI.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>python</category>
      <category>fastapi</category>
    </item>
    <item>
      <title>Agentic Commerce: Dive into ACP &amp; UCP Protocols</title>
      <dc:creator>Sreeharsha</dc:creator>
      <pubDate>Thu, 05 Feb 2026 10:48:11 +0000</pubDate>
      <link>https://dev.to/sraveend/agentic-commerce-dive-into-acp-ucp-protocols-4ahj</link>
      <guid>https://dev.to/sraveend/agentic-commerce-dive-into-acp-ucp-protocols-4ahj</guid>
      <description>&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;p&gt;Agentic commerce enables AI agents to autonomously handle end-to-end shopping workflows—from discovery to checkout—through standardized protocols like ACP (OpenAI/Stripe) and UCP (Shopify/Google). &lt;/p&gt;

&lt;p&gt;This article explores their architectures, a practical Shopify MCP implementation, engineering challenges, and future directions for developers building scalable agentic systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;E-commerce revolutionized retail by &lt;strong&gt;digitizing&lt;/strong&gt; physical stores into &lt;strong&gt;accessible, scalable&lt;/strong&gt; online platforms, enabling &lt;strong&gt;globalized&lt;/strong&gt; reach and streamlined checkout flows. Agentic commerce &lt;strong&gt;amplifies&lt;/strong&gt; these capabilities exponentially, empowering AI agents to &lt;strong&gt;autonomize&lt;/strong&gt; end-to-end purchases, &lt;strong&gt;negotiate&lt;/strong&gt; dynamic discounts, provide &lt;strong&gt;proactive&lt;/strong&gt; post-purchase support, and &lt;strong&gt;orchestrate&lt;/strong&gt; complex workflows—all while maintaining merchants as the Merchant of Record (MoR).&lt;/p&gt;

&lt;p&gt;This represents a paradigm shift from human-led browsing to &lt;strong&gt;AI-orchestrated&lt;/strong&gt; commerce, powered by interoperable protocols and robust system design. For engineers, it demands new skills in &lt;strong&gt;protocol interoperability&lt;/strong&gt;, &lt;strong&gt;stateful agent reasoning&lt;/strong&gt;, and &lt;strong&gt;headless commerce&lt;/strong&gt; integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview: Enabling Agentic Commerce
&lt;/h2&gt;

&lt;p&gt;To operationalize agentic commerce, open-source protocols provide the foundational building blocks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ACP (Agentic Commerce Protocol)&lt;/strong&gt; focuses on checkout and payment processing. It provides a REST-based Checkout API for cart management and a Delegate Payment API for secure payment tokenization through PSPs like Stripe. The minimal implementation surface enables rapid merchant adoption. &lt;a href="https://developers.openai.com/commerce/guides/get-started" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt; supports merchant integration via standardized &lt;a href="https://developers.openai.com/commerce/specs/feed" rel="noopener noreferrer"&gt;product feed specs&lt;/a&gt; that expose inventory to ChatGPT.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;UCP (Universal Commerce Protocol)&lt;/strong&gt; addresses the full commerce lifecycle including product discovery, identity linking, checkout, and order management. It defines participant roles, capability boundaries, and interaction patterns for complex commerce workflows. &lt;a href="https://shopify.dev/docs/agents" rel="noopener noreferrer"&gt;Shopify&lt;/a&gt; implements UCP through MCP servers for catalog and checkout, with ongoing development for post-purchase capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both protocols support &lt;em&gt;human-driven API&lt;/em&gt; workflows alongside agentic flows, ensuring &lt;em&gt;backward compatibility&lt;/em&gt; while &lt;em&gt;future-proofing&lt;/em&gt; for autonomous commerce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Protocols and Standards
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ACP
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;There are 4 parties involved in &lt;strong&gt;ACP&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Buyer&lt;/strong&gt;: human who wants to purchase something.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent&lt;/strong&gt;: AI platform that orchestrates checkout experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seller&lt;/strong&gt;: the merchant who sells products. Sellers implement the Checkout API and remain the merchant of record (MoR).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment Provider&lt;/strong&gt;: handles payment tokenization and processing. Eg: stripe.&lt;/li&gt;
&lt;/ul&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%2F171jrtfmjjvhsgm9l59d.jpeg" 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%2F171jrtfmjjvhsgm9l59d.jpeg" alt="ACP Architecture" width="762" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core APIs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.agenticcommerce.dev/docs/reference/checkout" rel="noopener noreferrer"&gt;Checkout API&lt;/a&gt;:&lt;br&gt;
Enables agents to programmatically create, update, and complete checkout sessions. Designed for conversational flows where agents maintain session state across multi-turn interactions while managing cart modifications, shipping calculations, and order finalization.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.agenticcommerce.dev/docs/reference/payments" rel="noopener noreferrer"&gt;Delegate Payment API&lt;/a&gt;:&lt;br&gt;
Provides tokenized payment credentials with granular usage constraints through an allowance framework. Merchants can enforce spending limits, merchant restrictions, and time-based controls without exposing raw payment credentials.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  UCP
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;There are 4 parties involved in &lt;strong&gt;UCP&lt;/strong&gt; as well:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Platform/Agent&lt;/strong&gt;: Buyer-facing interface (smart assistants, conversational surfaces, embedded commerce tools)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Business&lt;/strong&gt;: Product/service provider with inventory and fulfillment responsibilities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Credential Provider&lt;/strong&gt;: Identity management for user profile data (Google Sign-In, Entra ID)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment Provider&lt;/strong&gt;: Payment processing infrastructure (Stripe, PayPal, Google Pay)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;UCP&lt;/strong&gt; operates on three layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Capabilities&lt;/strong&gt; - Major Functional Domains: 

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Product Discovery&lt;/em&gt;: discovering products with semantic query support.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Cart&lt;/em&gt;: multi-item checkout, complex basket rules. Eg: BOGO, bundles, minimums&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Identity Linking&lt;/em&gt;: obtain authorization to perform actions on behalf of a user.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Checkout&lt;/em&gt;: facilitating checkout sessions.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Order&lt;/em&gt;: Transaction history, tracking, returns.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Other vertical capabilities&lt;/em&gt;: loyalty programs &amp;amp; member benefits.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Extensions&lt;/strong&gt; - Optional augmentation (e.g., discount codes, gift wrapping).&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Services&lt;/strong&gt;: lower-level communication layers used to exchange data. Eg: REST, MCP A2A&lt;/li&gt;

&lt;/ul&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%2Fwjd7ci5kejqdj2q7z4md.jpeg" 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%2Fwjd7ci5kejqdj2q7z4md.jpeg" alt="UCP Architecture" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Specifications&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ucp.dev/latest/specification/checkout/" rel="noopener noreferrer"&gt;Checkout Capability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ucp.dev/latest/specification/order/" rel="noopener noreferrer"&gt;Order Capability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ucp.dev/latest/specification/identity-linking/" rel="noopener noreferrer"&gt;Identity Linking Capability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ucp.dev/latest/specification/payment-handler-guide/" rel="noopener noreferrer"&gt;Payment Handler&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Active development: Product discovery with semantic search, cart operations with inventory validation, vertical-specific extension framework. See &lt;a href="https://ucp.dev/latest/documentation/roadmap/" rel="noopener noreferrer"&gt;roadmap&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&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%2Favgdg3vesxc661q08zfe.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%2Favgdg3vesxc661q08zfe.gif" alt="UI ACP Demo" width="720" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Shopify MCP Architecture
&lt;/h3&gt;

&lt;p&gt;Shopify implements UCP through two MCP servers that expose commerce primitives via JSON-RPC 2.0 protocol.&lt;/p&gt;

&lt;h4&gt;
  
  
  Catalog MCP Server
&lt;/h4&gt;

&lt;p&gt;Enables AI agents to search and discover products across the global Shopify ecosystem, providing cross-merchant product discovery capabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authentication&lt;/strong&gt;: OAuth client credentials flow returns JWT bearer tokens (60-minute TTL). All requests require &lt;code&gt;Authorization: Bearer {token}&lt;/code&gt; header.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Endpoint&lt;/strong&gt;: &lt;code&gt;https://discover.shopifyapps.com/global/mcp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core Tools&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;search_global_products&lt;/code&gt;&lt;/strong&gt;: Cross-merchant product search with filtering&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Required: &lt;code&gt;query&lt;/code&gt; (search terms), &lt;code&gt;context&lt;/code&gt; (buyer demographics, preferences)&lt;/li&gt;
&lt;li&gt;Filters: &lt;code&gt;min_price&lt;/code&gt;, &lt;code&gt;max_price&lt;/code&gt;, &lt;code&gt;ships_to&lt;/code&gt;, &lt;code&gt;ships_from&lt;/code&gt;, &lt;code&gt;available_for_sale&lt;/code&gt;, &lt;code&gt;requires_selling_plan&lt;/code&gt; (subscriptions), &lt;code&gt;include_secondhand&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Returns: Product list with titles, images, pricing, shop info, variants, UPIDs (Universal Product IDs)&lt;/li&gt;
&lt;li&gt;Limit: 1-300 results (default 10)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;get_global_product_details&lt;/code&gt;&lt;/strong&gt;: Lookup by UPID for comprehensive product data&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Required: &lt;code&gt;upid&lt;/code&gt; (Base62-encoded Universal Product ID)&lt;/li&gt;
&lt;li&gt;Optional: &lt;code&gt;product_options&lt;/code&gt; (filter by color, size, etc.), &lt;code&gt;option_preferences&lt;/code&gt; (rank option importance), &lt;code&gt;variant_id&lt;/code&gt; (force specific variant), &lt;code&gt;shop_id&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Returns: All variants with pricing, options, shop details, availability, shipping info&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Key Design Pattern&lt;/strong&gt;: Search returns UPIDs → lookup uses UPIDs for details. This two-step pattern enables agents to narrow results before retrieving full product data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Workflow&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;// Step 1: Search&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;method&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;tools/call&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;params&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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="s2"&gt;search_global_products&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;arguments&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;query&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;wireless headphones&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;context&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;noise-cancelling, budget-conscious&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;max_price&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ships_to&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;US&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;limit&lt;/span&gt;&lt;span class="dl"&gt;"&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Step 2: Get details with UPID from search results&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;method&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;tools/call&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;params&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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="s2"&gt;get_global_product_details&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;arguments&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;upid&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;AbC123XyZ&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;product_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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;key&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;Color&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;values&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Black&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Checkout MCP Server
&lt;/h4&gt;

&lt;p&gt;Enables AI agents to create and manage checkout sessions, allowing buyers to complete purchases through a trusted UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Authentication&lt;/strong&gt;: Same OAuth flow as Catalog MCP&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Endpoint&lt;/strong&gt;: &lt;code&gt;https://{shop-domain}/api/ucp/mcp&lt;/code&gt; (merchant-specific)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core Tools&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;create_checkout&lt;/code&gt;&lt;/strong&gt;: Initialize checkout session&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Required: &lt;code&gt;_meta.ucp.profile&lt;/code&gt; (agent UCP profile URI), &lt;code&gt;currency&lt;/code&gt;, &lt;code&gt;line_items&lt;/code&gt; (array with &lt;code&gt;quantity&lt;/code&gt; and variant &lt;code&gt;id&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Optional: &lt;code&gt;buyer&lt;/code&gt; (email), &lt;code&gt;fulfillment&lt;/code&gt; (shipping methods/destinations), &lt;code&gt;payment&lt;/code&gt; (instruments)&lt;/li&gt;
&lt;li&gt;Returns: Checkout ID, &lt;code&gt;status&lt;/code&gt;, line items with totals, &lt;code&gt;continue_url&lt;/code&gt; for trusted UI handoff, payment handlers&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;get_checkout&lt;/code&gt;&lt;/strong&gt;: Retrieve current session state&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Required: &lt;code&gt;id&lt;/code&gt; (checkout session ID)&lt;/li&gt;
&lt;li&gt;Returns: Current &lt;code&gt;status&lt;/code&gt;, line items, totals, messages (errors/warnings)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;update_checkout&lt;/code&gt;&lt;/strong&gt;: Modify session&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Supports: Line item changes, buyer info updates, shipping address, fulfillment method&lt;/li&gt;
&lt;li&gt;Line items replacement: Sending new &lt;code&gt;line_items&lt;/code&gt; array replaces existing cart&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;complete_checkout&lt;/code&gt;&lt;/strong&gt;: Finalize order&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Required: &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;idempotency_key&lt;/code&gt; (UUID), &lt;code&gt;payment.instrument_id&lt;/code&gt;, &lt;code&gt;payment.credential&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Only callable when &lt;code&gt;status == "ready_for_complete"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Returns: &lt;code&gt;order_id&lt;/code&gt;, &lt;code&gt;order_permalink_url&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;cancel_checkout&lt;/code&gt;&lt;/strong&gt;: Abandon session&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Required: &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;idempotency_key&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Non-reversible, frees inventory holds&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Status State Machine&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;incomplete → requires_escalation → ready_for_complete → complete_in_progress → completed
           ↓
         canceled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;incomplete&lt;/code&gt;: Missing required info, check &lt;code&gt;messages&lt;/code&gt; field for resolution steps&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;requires_escalation&lt;/code&gt;: Needs buyer input unavailable via API, use &lt;code&gt;continue_url&lt;/code&gt; for UI handoff&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ready_for_complete&lt;/code&gt;: All info collected, agent can call &lt;code&gt;complete_checkout&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Critical Design Principle&lt;/strong&gt;: Payment collection occurs in trusted UI (via &lt;code&gt;continue_url&lt;/code&gt;), not through agent. Agents never handle raw payment credentials. Checkout MCP receives tokenized payment data after user completes payment in secure interface.&lt;/p&gt;

&lt;p&gt;OpenAI's Responses API includes native MCP support with authentication, enabling straightforward integration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Demo Implementation: Terminal-Based Agentic Workflow
&lt;/h3&gt;

&lt;p&gt;Built a terminal interface demonstrating end-to-end agentic commerce:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User query: "find wireless headphones under $200"&lt;/li&gt;
&lt;li&gt;Agent queries Catalog MCP, returns results&lt;/li&gt;
&lt;li&gt;User requests product details&lt;/li&gt;
&lt;li&gt;User expresses purchase intent&lt;/li&gt;
&lt;li&gt;Agent initiates checkout (merchant store or embedded interface)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Repository&lt;/strong&gt;: &lt;a href="https://github.com/sreeharsha-rav/ai-apps/tree/main/acp-terminal-chat" rel="noopener noreferrer"&gt;Github - Agentic Commerce Terminal Chat&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Engineering Requirements
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;System Prompt Design&lt;/strong&gt;: LLM persona must balance autonomous progress with user confirmation requirements. Prompt defines tool invocation logic, state management across turns, and checkout progression. Poor calibration results in either unauthorized purchases or stalled workflows.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Incomplete Checkout Recovery&lt;/strong&gt;: Implement explicit fallback paths for payment failures, invalid addresses, and inventory depletion. Silent failures or hallucinated completions break user trust.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Product Identification from Context&lt;/strong&gt;: Extract product IDs from conversational references ("the second one", "the Sony model"). Requires mapping natural language to catalog entries before cart operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Authorization Flow&lt;/strong&gt;: Identity linking must clearly communicate data access scope and maintain secure token management across conversation sessions.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Implementation Challenges
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Context State Management&lt;/strong&gt;: The primary engineering challenge is maintaining accurate product context across multi-turn conversations. LLMs without structured state tracking produce errors when users reference products ambiguously, modify quantities, or switch between categories.&lt;/p&gt;

&lt;p&gt;Observed failure modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent adds wrong product to cart when user says "the second one" after viewing multiple result sets&lt;/li&gt;
&lt;li&gt;Quantity mismatches when user revises order mid-conversation&lt;/li&gt;
&lt;li&gt;Product ID loss during context window shifts in long sessions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Required state architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Active catalog context (current search results)
- User preference constraints (price limits, categories, attributes)
- Cart state (selected products, quantities, variants)
- Checkout session (shipping, payment, order status)
- Auth tokens and profile access scope
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Naive implementations relying solely on LLM conversation memory fail in production. Explicit state management with validation checkpoints is essential.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API State Synchronization&lt;/strong&gt;: Race conditions occur when users modify intent faster than API calls complete. Example: user changes quantity while cart update is in-flight. Requires optimistic UI updates with conflict resolution or pessimistic locking with clear loading states.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error Translation&lt;/strong&gt;: Commerce APIs return technical errors (inventory insufficient, payment declined, address validation failed). Engineers must translate these into natural language that helps users resolve issues without exposing implementation details or confusing non-technical users. Simple string mapping is insufficient—contextual explanation improves recovery rates.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Technical Trajectory
&lt;/h3&gt;

&lt;p&gt;Agentic commerce infrastructure is maturing rapidly. Near-term development areas include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vertical Protocol Extensions&lt;/strong&gt;: Industries with complex procurement workflows (automotive, B2B, real estate) will require domain-specific extensions beyond horizontal commerce primitives. Expect specification work on multi-stakeholder approval flows, negotiation protocols, and customization pipelines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-Agent Orchestration&lt;/strong&gt;: Single-agent architectures will evolve toward specialized agent coordination. A price comparison agent, reviews analyzer, and checkout executor could operate as microservices, requiring inter-agent communication protocols and distributed transaction management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context Persistence and Proactive Commerce&lt;/strong&gt;: As identity linking matures, agents gain access to richer user data, enabling proactive purchase suggestions based on detected needs rather than explicit requests. This requires careful consent management and notification preferences at the protocol level.&lt;/p&gt;

&lt;h3&gt;
  
  
  Collaboration
&lt;/h3&gt;

&lt;p&gt;If you're implementing agentic commerce systems and encountering state management issues, protocol integration challenges, or merchant-side architecture decisions, technical discussions are valuable for the ecosystem. Pattern sharing accelerates collective learning.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.spurtreetech.com/" rel="noopener noreferrer"&gt;Spurtree Technologies&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Agentic commerce protocols are open-source, implementation patterns are emerging, and the technical foundation is accessible. The architecture is still being defined through production deployments.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>design</category>
    </item>
    <item>
      <title>Caught in a Closure: Understanding Quirks in React State Management</title>
      <dc:creator>Sreeharsha</dc:creator>
      <pubDate>Mon, 13 Jan 2025 11:45:50 +0000</pubDate>
      <link>https://dev.to/sraveend/caught-in-a-closure-understanding-quirks-in-react-state-management-hmb</link>
      <guid>https://dev.to/sraveend/caught-in-a-closure-understanding-quirks-in-react-state-management-hmb</guid>
      <description>&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Closures are like backpacks that functions carry around, containing data from when they were created&lt;/li&gt;
&lt;li&gt;React components use closures to remember their state and props&lt;/li&gt;
&lt;li&gt;Stale closures can lead to bugs when state updates don't work as expected&lt;/li&gt;
&lt;li&gt;Functional updates provide a reliable solution for working with the latest state&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Have you ever wondered why sometimes your React state updates don't work quite right? Or why clicking a button multiple times quickly doesn't update the counter as expected? The answer lies in understanding closures and how React handles state updates. In this article, we'll unravel these concepts using simple examples that will make everything click.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a Closure?
&lt;/h3&gt;

&lt;p&gt;Think of a closure as a function that keeps a tiny memory of where it was born. It's like a polaroid snapshot of all the variables that existed when the function was created. Let's see this in action with a simple counter:&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;createPhotoAlbum&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;photoCount&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="c1"&gt;// This is our "snapshot" variable&lt;/span&gt;

    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addPhoto&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;photoCount&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="c1"&gt;// This function "remembers" photoCount&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;`Photos in album: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;photoCount&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getPhotoCount&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;`Current photos: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;photoCount&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;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addPhoto&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getPhotoCount&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;myAlbum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createPhotoAlbum&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;myAlbum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPhoto&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;     &lt;span class="c1"&gt;// "Photos in album: 1"&lt;/span&gt;
&lt;span class="nx"&gt;myAlbum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addPhoto&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;     &lt;span class="c1"&gt;// "Photos in album: 2"&lt;/span&gt;
&lt;span class="nx"&gt;myAlbum&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPhotoCount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// "Current photos: 2"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, both &lt;code&gt;addPhoto&lt;/code&gt; and &lt;code&gt;getPhotoCount&lt;/code&gt; functions remember the &lt;code&gt;photoCount&lt;/code&gt; variable, even after &lt;code&gt;createPhotoAlbum&lt;/code&gt; has finished executing. This is a closure in action - functions remembering their birthplace!&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Closures Matter in React
&lt;/h3&gt;

&lt;p&gt;In React, closures play a crucial role in how components remember their state. Here's a simple counter component:&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;Counter&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// This function closes over 'count'&lt;/span&gt;
        &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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="k"&gt;return &lt;/span&gt;&lt;span class="p"&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="o"&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;Count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;increment&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;Add&lt;/span&gt; &lt;span class="nx"&gt;One&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="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;increment&lt;/code&gt; function forms a closure around the &lt;code&gt;count&lt;/code&gt; state variable. This is how it "remembers" what number to add to when the button is clicked.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem: Stale Closures
&lt;/h3&gt;

&lt;p&gt;Here's where things get interesting. Let's create a situation where closures can cause unexpected behavior:&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;BuggyCounter&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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;incrementThreeTimes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// All these updates see the same 'count' value!&lt;/span&gt;
        &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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="c1"&gt;// count is 0&lt;/span&gt;
        &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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="c1"&gt;// count is still 0&lt;/span&gt;
        &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&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="c1"&gt;// count is still 0!&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;incrementThreeTimes&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;Add&lt;/span&gt; &lt;span class="nx"&gt;Three&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="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;If you click this button, you might expect the count to increase by 3. But surprise! It only goes up by 1. This is because of a "stale closure" - our function is stuck looking at the original value of &lt;code&gt;count&lt;/code&gt; when it was created.&lt;/p&gt;

&lt;p&gt;Think of it like taking three photos of a whiteboard showing the number 0, then trying to add 1 to each photo. You'll still have 0 in each photo!&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution: Functional Updates
&lt;/h3&gt;

&lt;p&gt;React provides a elegant solution to this problem - functional updates:&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;FixedCounter&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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;incrementThreeTimes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Each update builds on the previous one&lt;/span&gt;
        &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;current&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="c1"&gt;// 0 -&amp;gt; 1&lt;/span&gt;
        &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;current&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="c1"&gt;// 1 -&amp;gt; 2&lt;/span&gt;
        &lt;span class="nf"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;current&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="c1"&gt;// 2 -&amp;gt; 3&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&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;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;incrementThreeTimes&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;Add&lt;/span&gt; &lt;span class="nx"&gt;Three&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="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;Instead of using the value from our closure, we're now telling React "take whatever the current value is and add one to it." It's like having a helpful assistant who always looks at the current number on the whiteboard before adding to it!&lt;/p&gt;

&lt;h3&gt;
  
  
  Real World Example: Social Media Like Button
&lt;/h3&gt;

&lt;p&gt;Let's see how this applies to a real-world scenario - a social media post's like button:&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;SocialMediaPost&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;likes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setLikes&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isProcessing&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsProcessing&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Buggy version - might miss rapid clicks&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleLikeBuggy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isProcessing&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="nf"&gt;setIsProcessing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;updateLikeInDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;likes&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="c1"&gt;// Uses stale 'likes' value&lt;/span&gt;
        &lt;span class="nf"&gt;setLikes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;likes&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;setIsProcessing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="c1"&gt;// Fixed version - captures all clicks&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleLikeFixed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isProcessing&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="nf"&gt;setIsProcessing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Use functional updates to ensure we've got the latest count&lt;/span&gt;
        &lt;span class="nf"&gt;setLikes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentLikes&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;updateLikeInDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentLikes&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;currentLikes&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;setIsProcessing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleLikeFixed&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;Like&lt;/span&gt; &lt;span class="nc"&gt;Post &lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;likes&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;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Closures&lt;/strong&gt; are functions that remember the variables from where they were created - like functions with memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stale closures&lt;/strong&gt; happen when your function is using outdated values from its memory instead of current values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Functional updates&lt;/strong&gt; in React (&lt;code&gt;setCount(count =&amp;gt; count + 1)&lt;/code&gt;) ensure you're always working with the most current state.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Remember: When updating state based on its previous value, prefer functional updates. It's like having a reliable assistant who always checks the current value before making changes, rather than working from memory!&lt;/p&gt;

&lt;h3&gt;
  
  
  Best Practices
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use functional updates when the new state depends on the previous state&lt;/li&gt;
&lt;li&gt;Be especially careful with closures in async operations and event handlers&lt;/li&gt;
&lt;li&gt;When in doubt, console.log your values to check for stale closures&lt;/li&gt;
&lt;li&gt;Consider using the React DevTools to debug state updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these concepts under your belt, you're well-equipped to handle state updates in React like a pro! Happy coding! 🚀&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>react</category>
      <category>programming</category>
    </item>
    <item>
      <title>DOM Manipulation from Simple Updates to Virtual DOM</title>
      <dc:creator>Sreeharsha</dc:creator>
      <pubDate>Wed, 08 Jan 2025 17:31:32 +0000</pubDate>
      <link>https://dev.to/sraveend/dom-manipulation-from-simple-updates-to-virtual-dom-1j0c</link>
      <guid>https://dev.to/sraveend/dom-manipulation-from-simple-updates-to-virtual-dom-1j0c</guid>
      <description>&lt;h1&gt;
  
  
  TLDR
&lt;/h1&gt;

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

&lt;p&gt;When building web applications, one of the most fundamental challenges developers face is efficiently updating the Document Object Model (DOM) in response to user interactions and state changes. Let's explore this concept by examining three different implementations of a todo application, each showcasing a different approach to DOM manipulation.&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%2Fkx20ustdqwhw9iwk588c.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%2Fkx20ustdqwhw9iwk588c.gif" alt="Todo App" width="622" height="636"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Github: &lt;a href="https://github.com/sreeharsha-rav/javascript_projects/blob/main/todo-app/README.md" rel="noopener noreferrer"&gt;https://github.com/sreeharsha-rav/javascript_projects/blob/main/todo-app/README.md&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Evolution of DOM Updates
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Direct DOM Manipulation: The Simple Approach
&lt;/h3&gt;

&lt;p&gt;In our first implementation, we used the most straightforward approach: directly manipulating the DOM whenever a change occurred. Here's a simplified version of how we handled adding a new todo:&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;addTodo&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;todoText&lt;/span&gt; &lt;span class="o"&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;value&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;todoElement&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;todoElement&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;todoText&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;todoList&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;todoElement&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 approach is intuitive and works well for simple applications, but it has limitations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each operation directly touches the DOM&lt;/li&gt;
&lt;li&gt;No central place to track the application's state&lt;/li&gt;
&lt;li&gt;Difficult to maintain consistency across multiple updates&lt;/li&gt;
&lt;li&gt;Can become inefficient with frequent updates&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. State-Based DOM Manipulation: Adding Structure
&lt;/h3&gt;

&lt;p&gt;Our second implementation introduced the concept of state management. Instead of directly manipulating the DOM, we maintained a central state and updated the DOM based on that state:&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;todoStore&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;Map&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;addTodo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Update state&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="nx"&gt;nextId&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;todoStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Update DOM&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;todoElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createTodoElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;todoList&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;todoElement&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 approach brought several improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear separation between data (state) and presentation (DOM)&lt;/li&gt;
&lt;li&gt;More predictable application behavior&lt;/li&gt;
&lt;li&gt;Easier to implement features like undo/redo&lt;/li&gt;
&lt;li&gt;Better organization of code&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, we still faced a challenge: ensuring our DOM updates were efficient and maintaining consistency between our state and the UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Virtual DOM-like Approach: Smart Updates
&lt;/h3&gt;

&lt;p&gt;Our final implementation introduced a simple virtual DOM-like mechanism using state diffing. This approach represents a significant leap in sophistication:&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;let&lt;/span&gt; &lt;span class="nx"&gt;todoState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;      &lt;span class="c1"&gt;// Current state&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;oldTodoState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;   &lt;span class="c1"&gt;// Previous state&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newTodos&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Find what changed&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;added&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newTodos&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;newTodo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
        &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;oldTodoState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oldTodo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;oldTodo&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;newTodo&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deleted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;oldTodoState&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;oldTodo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; 
        &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;newTodos&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newTodo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;newTodo&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;oldTodo&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;// ... find updated items&lt;/span&gt;

    &lt;span class="c1"&gt;// Update only what changed&lt;/span&gt;
    &lt;span class="nx"&gt;added&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;todo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;addTodoElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nx"&gt;deleted&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;todo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;removeTodoElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&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="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;updateTodoElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// Save current state for next comparison&lt;/span&gt;
    &lt;span class="nx"&gt;oldTodoState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;newTodos&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Understanding Reconciliation and Diffing
&lt;/h2&gt;

&lt;p&gt;The concept of reconciliation, popularized by React, is about efficiently updating the DOM to match our desired state. Our simple implementation demonstrates three key aspects:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. State Comparison
&lt;/h3&gt;

&lt;p&gt;We maintain two versions of our state: current and previous. This allows us to detect exactly what changed between updates. The process of finding these differences is called "diffing."&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Minimal Updates
&lt;/h3&gt;

&lt;p&gt;Instead of rebuilding everything, we only update what changed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New items are added to the DOM&lt;/li&gt;
&lt;li&gt;Removed items are deleted from the DOM&lt;/li&gt;
&lt;li&gt;Modified items are updated in place&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Batch Processing
&lt;/h3&gt;

&lt;p&gt;All our DOM updates happen in a single pass, after we've calculated all the differences. This is more efficient than making updates one at a time as changes occur.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Benefits of Smart DOM Manipulation
&lt;/h2&gt;

&lt;p&gt;As we progressed through these implementations, we gained several advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: By only updating what changed, we minimize expensive DOM operations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Predictability&lt;/strong&gt;: With a single source of truth (our state), it's easier to understand and debug our application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: The diffing approach remains efficient even as our application grows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainability&lt;/strong&gt;: Clear separation of concerns makes our code easier to understand and modify.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Real-World Implications
&lt;/h2&gt;

&lt;p&gt;While our implementation is simplified, it demonstrates the core concepts behind modern frontend frameworks like React. The actual Virtual DOM implementation in React is more sophisticated, handling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complex nested structures&lt;/li&gt;
&lt;li&gt;Event delegation&lt;/li&gt;
&lt;li&gt;Component lifecycle&lt;/li&gt;
&lt;li&gt;Batched updates&lt;/li&gt;
&lt;li&gt;Cross-browser compatibility&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The evolution of our todo application shows how different approaches to DOM manipulation come with different trade-offs. While direct manipulation is simpler to understand and implement, a more structured approach with state management and smart updates leads to more maintainable and scalable applications.&lt;/p&gt;

&lt;p&gt;The concepts of reconciliation and diffing, even in their simplified form, demonstrate why modern frameworks like React are so powerful. They handle these complex updates automatically, allowing developers to focus on building features rather than optimizing DOM updates.&lt;/p&gt;

&lt;p&gt;As web applications become more complex, understanding these fundamental concepts becomes increasingly important. Whether you're using a framework or building something from scratch, knowing how and why DOM updates work the way they do will make you a more effective developer.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>programming</category>
    </item>
    <item>
      <title>Accelerating Open Source Impact: Harnessing the Power of Cloud Development</title>
      <dc:creator>Sreeharsha</dc:creator>
      <pubDate>Tue, 10 Sep 2024 00:30:41 +0000</pubDate>
      <link>https://dev.to/sraveend/accelerating-open-source-impact-harnessing-the-power-of-cloud-development-27eg</link>
      <guid>https://dev.to/sraveend/accelerating-open-source-impact-harnessing-the-power-of-cloud-development-27eg</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Open Source Software (OSS) contributions provide valuable real-world development experience&lt;/li&gt;
&lt;li&gt;Tools like OpenSauced help track and manage OSS contributions&lt;/li&gt;
&lt;li&gt;Local development environments can pose challenges for OSS work&lt;/li&gt;
&lt;li&gt;Cloud development environments (like GitHub Codespaces, CodeSandbox, and Gitpod) offer solutions to these challenges&lt;/li&gt;
&lt;li&gt;Benefits of cloud environments include consistency, resource efficiency, accessibility, and rapid onboarding&lt;/li&gt;
&lt;li&gt;Adopting cloud development environments can significantly enhance your OSS contribution workflow&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Open source software (OSS) development offers a unique opportunity to gain real-world experience that personal side projects often can't match. By contributing to OSS projects, developers can collaborate with others, tackle complex problems, and make meaningful impacts on widely-used software. In this post, I'll share my journey into OSS contributions, highlight some key tools that have aided my progress, and discuss how cloud development environments have revolutionized my workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tracking Contributions with OpenSauced
&lt;/h2&gt;

&lt;p&gt;One tool that has significantly enhanced my OSS contribution experience is &lt;a href="https://opensauced.pizza/docs/contributors/contributors-guide-to-open-sauced/" rel="noopener noreferrer"&gt;OpenSauced&lt;/a&gt;. This platform helps developers track their contributions, manage issues, and monitor repository activity. It's an invaluable resource for both newcomers and seasoned contributors alike. &lt;br&gt;
You can view my developer card &lt;a href="https://app.opensauced.pizza/u/sreeharsha-rav/card" rel="noopener noreferrer"&gt;here&lt;/a&gt;, which showcases some of my recent contributions and highlights.&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%2Fiqu3bmxg86wmdscbz549.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%2Fiqu3bmxg86wmdscbz549.png" alt="Opensauced Dev Card" width="800" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge: Setting Up Development Environments
&lt;/h2&gt;

&lt;p&gt;As I delved deeper into OSS contributions, I encountered a significant hurdle: setting up development environments. Initially, my approach was straightforward – clone repositories to my local system, create branches, implement changes, test, and submit pull requests (PRs). However, this method presented several challenges:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Resource Intensive:&lt;/strong&gt; Running multiple projects, especially those requiring Docker containers, significantly slowed down my local system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inconsistent Environments:&lt;/strong&gt; Solutions that worked on my local machine sometimes failed during CI/CD checks in GitHub Actions, leading to frustrating inconsistencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System Limitations:&lt;/strong&gt; Local hardware constraints often hindered my ability to work on more demanding projects.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These issues prompted me to seek out more efficient solutions, leading me to discover the world of cloud development environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cloud Development Environments: A Game-Changer
&lt;/h2&gt;

&lt;p&gt;Cloud development environments offer a powerful solution to the challenges of local development setups. They provide instant, consistent, and resource-efficient workspaces that integrate seamlessly with version control systems like Git. Here are three platforms I've found particularly useful:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://docs.github.com/en/codespaces" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub Codespaces&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Seamlessly integrated with GitHub repositories&lt;/li&gt;
&lt;li&gt;Instant development environment on any branch&lt;/li&gt;
&lt;li&gt;Excellent for simple to medium complexity projects&lt;/li&gt;
&lt;li&gt;Offers a generous tier for students and affordable paid plans&lt;/li&gt;
&lt;li&gt;Provides an intuitive web-based editor for quick edits and development&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://codesandbox.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;CodeSandbox&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Easy GitHub repository import functionality&lt;/li&gt;
&lt;li&gt;Generous free tier for developers&lt;/li&gt;
&lt;li&gt;Offers an online web IDE for immediate coding&lt;/li&gt;
&lt;li&gt;Requires additional configuration with an extension for VS Code development&lt;/li&gt;
&lt;li&gt;Robust enough for more demanding development environments&lt;/li&gt;
&lt;li&gt;Supports complex project setups with ease&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.gitpod.io/" rel="noopener noreferrer"&gt;&lt;strong&gt;Gitpod&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shares many features with CodeSandbox&lt;/li&gt;
&lt;li&gt;Provides a generous free tier for users&lt;/li&gt;
&lt;li&gt;More versatile, offering both a web editor and local editor integration&lt;/li&gt;
&lt;li&gt;Enables easy development with just a browser extension&lt;/li&gt;
&lt;li&gt;Capable of handling demanding and intricate development environments&lt;/li&gt;
&lt;li&gt;Strong integration with GitHub workflows for seamless contribution&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each of these platforms offers unique advantages, catering to different development needs and preferences. GitHub Codespaces excels in its tight integration with GitHub, while CodeSandbox offers flexibility with its web IDE. Gitpod stands out with its robust feature set, supporting both web and local development workflows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Honorable Mentions
&lt;/h3&gt;

&lt;p&gt;While not as fully featured for OSS contributions, these platforms are worth noting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://stackblitz.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Stackblitz:&lt;/strong&gt;&lt;/a&gt; Great for quick prototyping, but lacks integrated PR submission workflows.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://replit.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Replit:&lt;/strong&gt;&lt;/a&gt; Offers easy setup, but uses a custom editor and requires additional step for PR submissions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Benefits of Cloud Development Environments for OSS Contributions
&lt;/h2&gt;

&lt;p&gt;Adopting cloud development environments has significantly improved my OSS contribution workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Consistency:&lt;/strong&gt; Eliminated environment-related discrepancies between local development and CI/CD pipelines.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Efficiency:&lt;/strong&gt; Freed up local system resources, allowing for smoother multitasking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Accessibility:&lt;/strong&gt; Enabled contribution from any device with a web browser, increasing flexibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rapid Onboarding:&lt;/strong&gt; Reduced the time and effort required to set up new project environments.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;For those looking to start or enhance their OSS contributions, leveraging cloud development environments can be a game-changer. These tools not only simplify the setup process but also ensure consistency and efficiency in your development workflow. By embracing these cloud platforms, contributors can significantly streamline their open source journey, reducing setup time and ensuring consistent development experiences across different projects.&lt;/p&gt;

&lt;p&gt;Key takeaways from adopting cloud development environments for OSS contributions include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Simplified Workflow:&lt;/strong&gt; Cloud environments streamline the entire contribution process, from initial setup to final PR submission.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Increased Productivity:&lt;/strong&gt; With reduced setup times and consistent environments, you can focus more on coding and less on troubleshooting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Collaboration:&lt;/strong&gt; Cloud platforms facilitate easier code sharing and real-time collaboration with other contributors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contribution Tracking:&lt;/strong&gt; Tools like OpenSauced allow you to track and highlight your contributions, providing visibility to your OSS work.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As I continue my journey in open source, I'm excited to explore more projects and contribute more meaningfully, armed with these powerful cloud-based tools. The combination of cloud development environments and contribution tracking platforms like OpenSauced has truly transformed my approach to OSS development.&lt;/p&gt;

&lt;p&gt;Remember, the key to successful OSS contribution lies not just in the code you write, but also in the tools and practices you adopt. By embracing cloud development environments, you're setting yourself up for a more productive, enjoyable, and impactful contribution experience.&lt;/p&gt;

&lt;p&gt;Whether you're a seasoned developer or just starting your OSS journey, consider giving cloud development environments a try. They might just revolutionize your contribution workflow as they did mine.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>cloud</category>
      <category>development</category>
      <category>opensauced</category>
    </item>
    <item>
      <title>NeoChat: A Context-Aware RAG Chatbot Starter kit</title>
      <dc:creator>Sreeharsha</dc:creator>
      <pubDate>Sun, 01 Sep 2024 14:33:21 +0000</pubDate>
      <link>https://dev.to/sraveend/neochat-a-context-aware-rag-chatbot-starter-kit-19bf</link>
      <guid>https://dev.to/sraveend/neochat-a-context-aware-rag-chatbot-starter-kit-19bf</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/neon"&gt;Neon Open Source Starter Kit Challenge &lt;/a&gt;: Ultimate Starter Kit&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Kit
&lt;/h2&gt;

&lt;p&gt;This starter kit provides a foundation for building a Vue-based chatbot utilizing Retrieval Augmented Generation (RAG). It combines Nuxt, Neon, and OpenAI to create a powerful, context-aware chatbot application. The kit offers state management using Pinia, styling with NuxtUI, and a minimal chat interface integrated with Neon database as a vector store.&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%2Fy2py7c2cs0vz2yixlv4s.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%2Fy2py7c2cs0vz2yixlv4s.png" alt="NeoChat Image" width="800" height="728"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Use This Starter Kit?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ideal for developers looking to build AI chatbot applications using Vue.js&lt;/li&gt;
&lt;li&gt;Perfect for implementing Retrieval Augmented Generation in scenario-specific chatbots&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;RAG Architecture&lt;/strong&gt;: Implements a Retrieval-Augmented Generation system for accurate, context-aware responses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conversation History&lt;/strong&gt;: Stores chat history for enhanced context and continuity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Neon Postgres Integration&lt;/strong&gt;: Utilizes Neon Postgres as a vector database for efficient embedding storage and retrieval&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI Integration&lt;/strong&gt;: Leverages OpenAI's powerful language models for response generation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nuxt 3 Framework&lt;/strong&gt;: Built on Nuxt 3, offering a modern, performant foundation for web applications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS&lt;/strong&gt;: Utilizes Tailwind CSS for rapid UI development and easy customization&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modular Design&lt;/strong&gt;: Structured for easy understanding and extension of core functionalities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serverless-Ready&lt;/strong&gt;: Prepared for deployment on serverless platforms like Cloudflare, Netlify and Vercel.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Link to Kit
&lt;/h2&gt;

&lt;p&gt;Live Demo: &lt;a href="https://ai-apps-mu.vercel.app/" rel="noopener noreferrer"&gt;NeoChat Demo&lt;/a&gt;&lt;br&gt;
Repository: &lt;a href="https://github.com/sreeharsha-rav/ai-apps/blob/main/nuxt-rag-chat/README.md" rel="noopener noreferrer"&gt;NeoChat Starter Kit&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: Nuxt 3 application with Tailwind CSS for styling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Nuxt server routes for handling API requests&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vector Database&lt;/strong&gt;: Neon Postgres with pgvector for storing and querying document embeddings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Language Model&lt;/strong&gt;: OpenAI's &lt;code&gt;gpt-4o-mini&lt;/code&gt; model for generating responses and &lt;code&gt;text-embeddings-3-small&lt;/code&gt; for creating vector embeddings in &lt;em&gt;1536&lt;/em&gt; dimensions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RAG Pipeline&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;Query embedding&lt;/li&gt;
&lt;li&gt;Vector similarity search&lt;/li&gt;
&lt;li&gt;Context retrieval&lt;/li&gt;
&lt;li&gt;Response generation&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Development Journey
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Technology Stack Rationale
&lt;/h3&gt;

&lt;p&gt;The choice of technologies for this starter kit was driven by a desire to create a developer-friendly, efficient, and scalable solution for AI-powered chatbots.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nuxt&lt;/strong&gt;: Selected for its ability to create Vue-based fullstack applications with Server Side Rendering. Vue's developer-friendly nature encourages more developers to explore AI application development.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OpenAI&lt;/strong&gt;: Chosen for both the chatbot model and embeddings generation due to its developer-friendly interface and robust capabilities in creating embeddings and developing applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Neon DB&lt;/strong&gt;: Opted for as the serverless Postgres database solution, eliminating the need for manual configuration and autoscaling concerns. Its native support for vector embeddings using PGVector and intuitive developer dashboard significantly enhance the development experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Langchain&lt;/strong&gt;: Utilized to seamlessly integrate OpenAI and NeonDB for text loading, embedding generation, and Retrieval Augmented Generation (RAG) implementation.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Challenges and Solutions
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Optimizing Vector Embeddings&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Challenge&lt;/em&gt;: Determining the optimal chunk size and overlap for creating effective vector embeddings.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Solution&lt;/em&gt;: Extensive experimentation to find the right balance, ensuring the AI model had sufficient information to create meaningful embeddings.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enhancing Context Awareness&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Challenge&lt;/em&gt;: Creating a chatbot capable of providing rich, contextual answers beyond simple similarity searches.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Solution&lt;/em&gt;: Development of features to extract standalone questions, retrieve relevant embeddings, and synthesize information using an LLM. This process involved careful prompt engineering to achieve desired results.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Implementing Conversation History&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Challenge&lt;/em&gt;: Enabling the chatbot to make context-aware responses by referencing earlier messages.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Solution&lt;/em&gt;: Implementation of an in-memory array to store conversation history, leveraging Langchain to determine the appropriate sequence of prompts and calls.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Frontend Development&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Challenge&lt;/em&gt;: Creating an intuitive user interface for chatbot interactions.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Solution&lt;/em&gt;: Utilization of Vue and Nuxt as a meta-framework, allowing for the development of both frontend and backend components within a single framework. This approach simplified the build process and reduced configuration overhead.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Testing and Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Challenge&lt;/em&gt;: Resolving package dependency issues during the build and deployment phase.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Solution&lt;/em&gt;: Transition to a cloud-based editor to streamline the build process, followed by successful deployment on Vercel.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Value of Starter Kits
&lt;/h3&gt;

&lt;p&gt;This starter kit aims to simplify the process of creating context-aware chatbots by providing a ready-to-use project structure. It allows developers to focus on building and shipping features without the need to manually configure all components from scratch.&lt;/p&gt;

&lt;p&gt;Much like how Neon DB streamlines database integration for fullstack applications, this starter kit enables developers to concentrate on creating and deploying innovative features in AI-powered chat applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open for Contributions
&lt;/h3&gt;

&lt;p&gt;This project welcomes contributions from the community. Developers are encouraged to raise issues, request features, or submit pull requests to enhance this starter template. It serves as a foundation for building exciting new projects in the realm of AI-powered chat applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Acknowledgments
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The RAG logic implementation was greatly influenced by &lt;a href="https://v2.scrimba.com/the-official-langchainjs-course-c02t" rel="noopener noreferrer"&gt;The Official Langchain Course&lt;/a&gt; at Scrimba.&lt;/li&gt;
&lt;li&gt;The comprehensive documentation provided by Neon, Nuxt, and Langchain was instrumental in overcoming challenges and finding solutions throughout the development process.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>neonchallenge</category>
      <category>postgres</category>
      <category>database</category>
    </item>
    <item>
      <title>The Power of Pipes: Streamlining Data Flow in Backend Development</title>
      <dc:creator>Sreeharsha</dc:creator>
      <pubDate>Wed, 21 Aug 2024 04:12:02 +0000</pubDate>
      <link>https://dev.to/sraveend/the-power-of-pipes-streamlining-data-flow-in-backend-development-nhh</link>
      <guid>https://dev.to/sraveend/the-power-of-pipes-streamlining-data-flow-in-backend-development-nhh</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR:
&lt;/h2&gt;

&lt;p&gt;• Pipes evolved from Unix to modern TypeScript, including RxJS and LangChain&lt;br&gt;
• They boost code readability by 50%, cut complexity by 30%, and increase reusability by 40%&lt;br&gt;
• Ideal for backend tasks like user registration flows, langchain agents and observables&lt;/p&gt;
&lt;h2&gt;
  
  
  Why Pipes Matter
&lt;/h2&gt;

&lt;p&gt;Backend developers often struggle with:&lt;br&gt;
• Messy chains of operations&lt;br&gt;
• Hard-to-follow data flows&lt;br&gt;
• Limited reuse of processing steps&lt;br&gt;
• Lack of standard data transformation methods&lt;/p&gt;

&lt;p&gt;Pipes solve these issues by creating clear, modular data pipelines.&lt;br&gt;
The examples used in this article are provided here: &lt;a href="https://github.com/sreeharsha-rav/sw_basics/blob/main/advanced/pipe.ts" rel="noopener noreferrer"&gt;github&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  A Brief History
&lt;/h3&gt;

&lt;p&gt;• 1970s: Born in Unix (thanks, McIlroy and Thompson!)&lt;br&gt;
• Later: Adopted in functional programming (Haskell, F#)&lt;br&gt;
• Now: Widespread in JavaScript/TypeScript libraries&lt;/p&gt;
&lt;h3&gt;
  
  
  Pipes 101: A TypeScript Example
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Basic Pipe POC Implementation in TypeScript&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Func&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="o"&gt;&amp;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;arg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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;R&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;pipe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="nx"&gt;fns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Func&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Func&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&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="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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;fns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;f&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;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Detailed Pipe POC Example&lt;/strong&gt;&lt;br&gt;
Let's examine how pipes work with both string and number transformations:&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="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Func&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;R&lt;/span&gt;&lt;span class="o"&gt;&amp;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;arg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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;R&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;pipe&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&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="nx"&gt;fns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Func&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Func&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&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="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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;fns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;f&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;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// String transformation example&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;removeSpaces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;/g&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toLowerCase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;str&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;capitalize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charAt&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="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;str&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;1&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;addExclamation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;str&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;processString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;removeSpaces&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;addExclamation&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;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;  HeLLo   WoRLd  &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;str_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;processString&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;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;str_result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Output: "Helloworld!"&lt;/span&gt;

&lt;span class="c1"&gt;// Number transformation example&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;double&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="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;addTen&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="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;square&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="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;processNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;double&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;addTen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;square&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;num_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;processNumber&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="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;num_result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Output: 400&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How Pipes Work:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Function Composition:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;pipe&lt;/code&gt; function takes multiple functions as arguments and returns a new function.&lt;/li&gt;
&lt;li&gt;This new function, when called, will apply each of the input functions in sequence.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reducer Pattern:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Inside the returned function, &lt;code&gt;Array.reduce&lt;/code&gt; is used to apply each function sequentially.&lt;/li&gt;
&lt;li&gt;The result of each function becomes the input for the next function.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Type Flexibility:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The use of generics (&lt;code&gt;&amp;lt;T&amp;gt;&lt;/code&gt;) allows the pipe to work with any data type.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;Func&amp;lt;T, R&amp;gt;&lt;/code&gt; type ensures type safety between function inputs and outputs.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Execution Flow:&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For the string example:&lt;br&gt;
a. Input: "  HeLLo   WoRLd  "&lt;br&gt;
b. removeSpaces: "HeLLoWoRLd"&lt;br&gt;
c. toLowerCase: "helloworld"&lt;br&gt;
d. capitalize: "Helloworld"&lt;br&gt;
e. addExclamation: "Helloworld!"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the number example:&lt;br&gt;
a. Input: 5&lt;br&gt;
b. double: 5 * 2 = 10&lt;br&gt;
c. addTen: 10 + 10 = 20&lt;br&gt;
d. square: 20 * 20 = 400&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These examples demonstrate how pipes can simplify complex transformations by breaking them down into a series of smaller, manageable steps. This pattern is particularly useful in backend development for processing data through multiple stages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pipes in Different Contexts
&lt;/h3&gt;

&lt;p&gt;• &lt;strong&gt;RxJS&lt;/strong&gt;: Used for composing asynchronous and event-based programs&lt;br&gt;
   • &lt;strong&gt;Observables&lt;/strong&gt;: Applying a series of operators to a stream of data&lt;br&gt;
   • &lt;strong&gt;LangChain&lt;/strong&gt;: Chaining together multiple AI/ML operations in natural language processing tasks&lt;/p&gt;
&lt;h3&gt;
  
  
  Real-World Application: User Registration Flow
&lt;/h3&gt;

&lt;p&gt;Detailed sample implementation of a user registration process using pipes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;   &lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;pipe&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;your-library&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;UserInput&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&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;validateInput&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;UserInput&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;UserInput&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;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&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;password&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&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;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid input&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;return&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&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;normalizeEmail&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;UserInput&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;UserInput&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&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="p"&gt;};&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hashPassword&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserInput&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Omit&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserInput&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="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hashedPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hashedPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`hashed_&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;password&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hashedPassword&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;

   &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;hashedPassword&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="nl"&gt;createdAt&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="p"&gt;}&lt;/span&gt;

   &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createUserObject&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="nb"&gt;ReturnType&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;hashPassword&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;User&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toString&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;substr&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;9&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
       &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;hashedPassword&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;hashedPassword&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="na"&gt;createdAt&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;Date&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;processUserRegistration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="nx"&gt;validateInput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="nx"&gt;normalizeEmail&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="nx"&gt;hashPassword&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
     &lt;span class="nx"&gt;createUserObject&lt;/span&gt;
   &lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;processUserRegistration&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
       &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;  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="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password123&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="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="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;newUser&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;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Registration failed:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&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;Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Clear Visualization&lt;/em&gt;: The order of operations is clearly visible in the pipe definition.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Modularity&lt;/em&gt;: Each function performs a single, well-defined transformation.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Reusability&lt;/em&gt;: Individual functions can be reused in different pipes or contexts.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Extensibility&lt;/em&gt;: New transformations can be easily added to the pipe.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h3&gt;
  
  
  Benefits in Backend Development:
&lt;/h3&gt;

&lt;p&gt;• &lt;strong&gt;Cleaner code&lt;/strong&gt;: Say goodbye to nested function hell&lt;br&gt;
• &lt;strong&gt;Easier debugging&lt;/strong&gt;: Spot issues in specific pipeline steps&lt;br&gt;
• &lt;strong&gt;Flexible design&lt;/strong&gt;: Add or remove steps without breaking things&lt;br&gt;
• &lt;strong&gt;Better testing&lt;/strong&gt;: Test each pipe function separately&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Pipes make complex operations easy to read and maintain&lt;/li&gt;
&lt;li&gt;They're modular: mix and match functions as needed&lt;/li&gt;
&lt;li&gt;Versatile: Use for simple tasks or complex data flows&lt;/li&gt;
&lt;li&gt;Promotes good habits: immutability and side-effect-free coding&lt;/li&gt;
&lt;li&gt;Works in many languages, not just TypeScript&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Bottom Line:
&lt;/h3&gt;

&lt;p&gt;Pipes help tame the complexity beast in backend systems. Whether you're cleaning data, formatting API responses, or handling intricate business logic, pipes can make your code cleaner, more flexible, and easier to evolve.&lt;/p&gt;

</description>
      <category>backenddevelopment</category>
      <category>typescript</category>
      <category>programming</category>
      <category>coding</category>
    </item>
    <item>
      <title>Building a Scalable AI Translator with Next.js Pt 1: Leveraging Composition and Custom Hooks</title>
      <dc:creator>Sreeharsha</dc:creator>
      <pubDate>Thu, 15 Aug 2024 05:02:48 +0000</pubDate>
      <link>https://dev.to/sraveend/building-a-scalable-ai-translator-with-nextjs-pt-1-leveraging-composition-and-custom-hooks-gla</link>
      <guid>https://dev.to/sraveend/building-a-scalable-ai-translator-with-nextjs-pt-1-leveraging-composition-and-custom-hooks-gla</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;An AI Translator built using React and Next.js&lt;/li&gt;
&lt;li&gt;Key architectural approaches:

&lt;ul&gt;
&lt;li&gt;Component composition for modular UI&lt;/li&gt;
&lt;li&gt;Custom hooks for reusable logic&lt;/li&gt;
&lt;li&gt;Separation of concerns for maintainability&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Benefits: Reusability, testability, maintainability, and scalability&lt;/li&gt;

&lt;li&gt;Future improvements: Advanced state management, performance optimization, and enhanced error handling&lt;/li&gt;

&lt;/ul&gt;

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

&lt;p&gt;In modern web development, creating maintainable and scalable applications is crucial. This article explores the architectural decisions and design patterns used in building an AI Translator application using React and Next.js. The focus is on how composition and custom hooks can lead to a more modular, reusable, and maintainable codebase.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Overview:
&lt;/h2&gt;

&lt;p&gt;View the source code here &lt;a href="https://github.com/sreeharsha-rav/ai-apps/tree/main/ai-translator" rel="noopener noreferrer"&gt;ai-translator&lt;/a&gt;.&lt;br&gt;
Commit Hash: &lt;code&gt;commit 894ab7aa92a9821b888925c84fe01167d24891aa&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The AI Translator is a web application that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allows users to input text&lt;/li&gt;
&lt;li&gt;Provides translations in various languages&lt;/li&gt;
&lt;li&gt;Features a chat-like interface&lt;/li&gt;
&lt;li&gt;Uses OpenAI's API for translations&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Architectural Approach:
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Component Composition:
&lt;/h3&gt;

&lt;p&gt;The application is structured using a composition-based approach. &lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;The main component, AiChat, is composed of smaller, focused components&lt;/li&gt;
&lt;li&gt;Each component has a single responsibility&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ai-translator/src/components/AiChat.tsx&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AiChat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ... state and hooks ...&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ChatWindow&lt;/span&gt; &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;LanguageSelector&lt;/span&gt;
        &lt;span class="na"&gt;selectedLanguage&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;selectedLanguage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onLanguageChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleLanguageChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ChatInput&lt;/span&gt;
        &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;inputValue&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleInputChange&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;isDisabled&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;isTranslating&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better separation of concerns&lt;/li&gt;
&lt;li&gt;Each component is more focused and easier to maintain&lt;/li&gt;
&lt;li&gt;Improved readability and testability&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Custom Hooks:
&lt;/h3&gt;

&lt;p&gt;Complex logic is extracted into custom hooks.&lt;/p&gt;

&lt;p&gt;Key custom hooks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;useTranslation&lt;/code&gt;: Handles translation API calls&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useChat&lt;/code&gt;: Manages chat state and message handling&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;useLanguage&lt;/code&gt;: Manages language selection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example of &lt;code&gt;useChat&lt;/code&gt; hook:&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;// ai-translator/src/hooks/useChat.ts&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useChat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedLanguage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isTranslating&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsTranslating&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;translateText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useTranslation&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;addMessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;isUser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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="na"&gt;newMessage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="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="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="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isUser&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nf"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prev&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;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newMessage&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;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useCallback&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="na"&gt;inputValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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;// ... translation logic ...&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;selectedLanguage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isTranslating&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;addMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;translateText&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isTranslating&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&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;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separation of concerns&lt;/li&gt;
&lt;li&gt;Reusable logic across components&lt;/li&gt;
&lt;li&gt;Easier testing of complex logic&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Separation of Concerns:
&lt;/h3&gt;

&lt;p&gt;The application is separated into distinct layers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Presentation Layer: React components

&lt;ul&gt;
&lt;li&gt;Example: AiChat, TranslationInput, ChatInput&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Application Logic Layer: Custom hooks

&lt;ul&gt;
&lt;li&gt;Example: useChat, useTranslation, useLanguage&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Data Access Layer: API routes and services

&lt;ul&gt;
&lt;li&gt;Example: translationService&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Example of layer interaction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Presentation Layer&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AiChat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;FC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Application Logic Layer&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useChat&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ChatWindow&lt;/span&gt; &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ChatInput&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&amp;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;// Data Access Layer (in useChat hook)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;translateText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useTranslation&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;translatedText&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;translateText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputValue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;selectedLanguage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Modular code structure&lt;/li&gt;
&lt;li&gt;Easier to test and maintain&lt;/li&gt;
&lt;li&gt;Clear separation of responsibilities&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Benefits of This Approach:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Reusability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom hooks like &lt;code&gt;useTranslation&lt;/code&gt; can be reused across different components&lt;/li&gt;
&lt;li&gt;Example: Using &lt;code&gt;useTranslation&lt;/code&gt; in both chat and document translation features&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Testability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smaller, focused components and hooks are easier to unit test&lt;/li&gt;
&lt;li&gt;Example: Testing &lt;code&gt;useChat&lt;/code&gt; hook in isolation from UI components&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Maintainability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separation of concerns makes it easier to update or replace individual parts&lt;/li&gt;
&lt;li&gt;Example: Swapping out the translation API without affecting the UI components&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Scalability:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New features can be added by creating new components and hooks&lt;/li&gt;
&lt;li&gt;Example: Adding a voice translation feature by creating new components and hooks without significantly impacting existing code&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Further Improvements:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;State Management:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement global state management for larger applications&lt;/li&gt;
&lt;li&gt;Example: Using Redux for managing user preferences across the app&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Performance Optimization:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement memoization techniques&lt;/li&gt;
&lt;li&gt;Use virtualization for long message lists&lt;/li&gt;
&lt;li&gt;Example:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MemoizedChatWindow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;memo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ChatWindow&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;optimizedMessages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMemo&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;processMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Error Handling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement a robust error handling strategy&lt;/li&gt;
&lt;li&gt;Example: Creating a &lt;code&gt;useError&lt;/code&gt; hook for managing and displaying errors across the app&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Accessibility:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure all components are accessible&lt;/li&gt;
&lt;li&gt;Example: Creating a &lt;code&gt;useFocus&lt;/code&gt; hook for managing focus in the chat interface&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Internationalization:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implement a language switching feature for the UI&lt;/li&gt;
&lt;li&gt;Example: Using react-i18next for managing UI translations&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Code Splitting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Utilize Next.js's built-in code splitting features&lt;/li&gt;
&lt;li&gt;Example: Using dynamic imports for less frequently used components&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;By leveraging composition and custom hooks, a scalable and maintainable architecture has been created for the AI Translator application. This approach allows for easy extension and modification, setting a solid foundation for future development. As the application continues to evolve, the focus will be on further optimizations and enhancements to improve performance and user experience.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>react</category>
      <category>programming</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Basic React Design Patterns: A practical look with Tic Tac Toe</title>
      <dc:creator>Sreeharsha</dc:creator>
      <pubDate>Mon, 29 Jul 2024 15:50:27 +0000</pubDate>
      <link>https://dev.to/sraveend/basic-react-design-patterns-a-practical-look-with-tic-tac-toe-3c76</link>
      <guid>https://dev.to/sraveend/basic-react-design-patterns-a-practical-look-with-tic-tac-toe-3c76</guid>
      <description>&lt;h2&gt;
  
  
  TLDR:
&lt;/h2&gt;

&lt;p&gt;This article explores React design patterns through a Tic Tac Toe game implemented with TypeScript, covering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Functional Components with TypeScript&lt;/li&gt;
&lt;li&gt;Hooks for State Management&lt;/li&gt;
&lt;li&gt;Prop Typing for Type Safety&lt;/li&gt;
&lt;li&gt;Composition of Components&lt;/li&gt;
&lt;li&gt;Container and Presentational Components&lt;/li&gt;
&lt;li&gt;Stateful and Stateless Components&lt;/li&gt;
&lt;li&gt;Higher-Order Components (HOCs)&lt;/li&gt;
&lt;li&gt;Render Props&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These patterns enhance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type safety&lt;/li&gt;
&lt;li&gt;Code organization&lt;/li&gt;
&lt;li&gt;Reusability&lt;/li&gt;
&lt;li&gt;Maintainability&lt;/li&gt;
&lt;li&gt;Separation of concerns&lt;/li&gt;
&lt;li&gt;Testability of React applications&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;React, combined with TypeScript, offers a powerful toolkit for building robust web applications. Let's explore both fundamental and advanced React patterns using a Tic Tac Toe game as our example, providing simple explanations for each pattern.&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%2Fnug059ktzt9cs7rt54al.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%2Fnug059ktzt9cs7rt54al.gif" alt=" " width="600" height="534"&gt;&lt;/a&gt;&lt;br&gt;
You can reference the code here while going through the article for more clarity: &lt;a href="https://github.com/sreeharsha-rav/frontend-projects/tree/main/tic-tac-toe" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Project Structure
&lt;/h2&gt;

&lt;p&gt;Our Tic Tac Toe project is organized 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;tic-tac-toe
├── src/
│   ├── components/
│   │   ├── ui/         # Reusable UI components
│   │   ├── Board.tsx   # Tic Tac Toe board
│   │   ├── Game.tsx    # Game component
│   │   ├── Square.tsx  # Square component
│   │   └── Score.tsx   # Score component
│   ├── App.tsx         # Main app component
│   └── main.tsx        # Entry point
|   ...                 # more config files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Design Patterns and Implementation:
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Functional Components and Prop Typing:
&lt;/h3&gt;

&lt;p&gt;Functional components with explicitly typed props ensure type safety and self-documenting code.&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;// Square.tsx&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Square&lt;/span&gt;&lt;span class="p"&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="nx"&gt;onClick&lt;/span&gt; &lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onClick&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="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&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;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;square&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onClick&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;value&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;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ELI5: Imagine you're building with special Lego bricks. Each brick (component) has a specific shape (props) that only fits in certain places. TypeScript is like a magic ruler that makes sure you're using the right bricks in the right spots.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Composition:
&lt;/h3&gt;

&lt;p&gt;Building complex UIs from smaller, reusable components promotes modularity and reusability.&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;// Board.tsx&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Board&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;}:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;board&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)[],&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;board_items&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;board&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;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Square&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&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;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;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&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;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. State Management with Hooks:
&lt;/h3&gt;

&lt;p&gt;Using useState and useEffect hooks simplifies state management in functional components.&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;// Game.tsx&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setBoard&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&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="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&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="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentPlayer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCurrentPlayer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;gameOver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setGameOver&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&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;useEffect&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;aiOpponent&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;currentPlayer&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;O&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;gameOver&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;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;makeAIMove&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="k"&gt;return &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;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;timer&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;board&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentPlayer&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Container and Presentational Components:
&lt;/h3&gt;

&lt;p&gt;This pattern separates logic (containers) from rendering (presentational components).&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;// Game.tsx (Container Component)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;TicTacToe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;aiOpponent&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="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setBoard&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&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="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&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="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;currentPlayer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCurrentPlayer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// ... game logic&lt;/span&gt;

    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&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;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;wrapper&lt;/span&gt;&lt;span class="p"&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;Board&lt;/span&gt; &lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&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;Score&lt;/span&gt; &lt;span class="nx"&gt;x_wins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;xWins&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;o_wins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;oWins&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&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="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Board.tsx (Presentational Component)&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Board&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;className&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;board_items&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;board&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;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Square&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&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;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;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&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;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Stateful and Stateless Components:
&lt;/h3&gt;

&lt;p&gt;This concept involves minimizing the number of stateful components to simplify data flow. In our implementation, &lt;code&gt;TicTacToe&lt;/code&gt; is stateful (manages game state), while &lt;code&gt;Square&lt;/code&gt;, &lt;code&gt;Board&lt;/code&gt;, and &lt;code&gt;Score&lt;/code&gt; are stateless (receive data via props).&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Higher-Order Components (HOCs):
&lt;/h3&gt;

&lt;p&gt;HOCs are functions that take a component and return a new component with additional props or behavior.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;withAIOpponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;WrappedComponent&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="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;aiEnabled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setAiEnabled&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&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="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;label&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="kd"&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;checkbox&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
            &lt;span class="nx"&gt;checked&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;aiEnabled&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
            &lt;span class="nx"&gt;onChange&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="nf"&gt;setAiEnabled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;aiEnabled&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
          &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;          &lt;span class="nx"&gt;Play&lt;/span&gt; &lt;span class="nx"&gt;against&lt;/span&gt; &lt;span class="nx"&gt;AI&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/label&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;WrappedComponent&lt;/span&gt; &lt;span class="p"&gt;{...&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;aiOpponent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;aiEnabled&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&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;/&lt;/span&gt;&lt;span class="err"&gt;&amp;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;TicTacToeWithAI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;withAIOpponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;TicTacToe&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7. Render Props:
&lt;/h3&gt;

&lt;p&gt;This pattern involves passing rendering logic as a prop to a component.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;GameLogic&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;render&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="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setBoard&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&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="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="c1"&gt;// ... game logic&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt; &lt;span class="p"&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;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;GameLogic&lt;/span&gt; 
      &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{({&lt;/span&gt; &lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;handleClick&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Board&lt;/span&gt; &lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;board&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleClick&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;By implementing these design patterns in our TypeScript-based Tic Tac Toe game, we've created a modular, type-safe, and maintainable application. These patterns promote:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean and efficient code&lt;/li&gt;
&lt;li&gt;Improved readability&lt;/li&gt;
&lt;li&gt;Enhanced scalability&lt;/li&gt;
&lt;li&gt;Better separation of concerns&lt;/li&gt;
&lt;li&gt;Increased reusability&lt;/li&gt;
&lt;li&gt;Easier testing and debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you build more complex React applications, these patterns will serve as valuable tools in your development toolkit, allowing you to create applications that are not only functional but also clean, efficient, and easy to maintain and extend.&lt;/p&gt;

</description>
      <category>react</category>
      <category>designpatterns</category>
      <category>typescript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>A Photo Caption API</title>
      <dc:creator>Sreeharsha</dc:creator>
      <pubDate>Sun, 09 Jun 2024 00:16:13 +0000</pubDate>
      <link>https://dev.to/sraveend/a-photo-caption-api-f90</link>
      <guid>https://dev.to/sraveend/a-photo-caption-api-f90</guid>
      <description>&lt;p&gt;&lt;strong&gt;tl;dr:&lt;/strong&gt;&lt;br&gt;
A Photo Caption Contest API has been successfully built and launched using Node.js, Fastify, and TypeScript. This project demonstrates key backend concepts including user authentication, image management, and caption submission. By implementing basic caching, response times for frequently accessed endpoints were reduced by 30%, showcasing the impact of simple performance optimizations.&lt;/p&gt;

&lt;p&gt;You can check out the code here: &lt;a href="https://github.com/sreeharsha-rav/typescript-projects/tree/main/photo-caption" rel="noopener noreferrer"&gt;Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context&lt;/strong&gt;&lt;br&gt;
In the landscape of viral memes and image-driven content, a Photo Caption Contest platform presents an excellent opportunity to apply backend development skills. This project, inspired by the Codecademy "Back-End Engineer" course, serves as a practical application of user interaction, data management, and performance optimization concepts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test Setup&lt;/strong&gt;&lt;br&gt;
The RESTful API built for this project demonstrates several fundamental backend concepts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User Authentication: JWT-based authentication for user registration and login, showcasing secure password hashing and token management.&lt;/li&gt;
&lt;li&gt;Image Management: Functionality for users to upload images and for the API to serve these images, covering file upload handling and static content serving.&lt;/li&gt;
&lt;li&gt;Caption Submission: Users can submit captions for images, a feature that involved designing relational database schemas using Prisma ORM with PostgreSQL.&lt;/li&gt;
&lt;li&gt;Performance Optimization: Node-Cache was used to cache responses for frequently accessed endpoints, demonstrating the significant performance gains possible with even basic caching strategies.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Results&lt;/strong&gt;&lt;br&gt;
After launching the API and testing it with a Postman collection, several positive outcomes were observed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;30% Faster Response Times: By caching GET requests for images and their captions, response times dropped by 30%. This underscores how basic caching can substantially enhance API performance.&lt;/li&gt;
&lt;li&gt;Relational Data Handling: Successfully retrieving images with their associated captions validated the effectiveness of the chosen ORM (Prisma) in handling relational data.&lt;/li&gt;
&lt;li&gt;Authentication Flow: Proper user registration, login, and token-based access to protected routes (like posting images and captions) confirmed the robustness of the authentication and authorization implementation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One challenge encountered was a slight increase in response time for non-cached requests due to the additional caching logic. However, the performance gain for cached responses more than compensates for this, illustrating the trade-offs inherent in optimization strategies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next Steps&lt;/strong&gt;&lt;br&gt;
This project lays the groundwork for exploring more advanced backend development concepts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;API Documentation: Implement Swagger to document the API. This enhances the developer experience for frontend developers or other API consumers by providing clear, interactive API documentation.&lt;/li&gt;
&lt;li&gt;Advanced Caching: Replace Node-Cache with Redis. This step introduces in-memory data structures and more sophisticated caching strategies, essential for handling increased traffic.&lt;/li&gt;
&lt;li&gt;Testing: Increase test coverage using Jest. Comprehensive unit and integration testing are crucial for maintaining code quality and facilitating safe, rapid development.&lt;/li&gt;
&lt;li&gt;Containerization: Dockerize the application. This foray into DevOps teaches how to create reproducible, easy-to-deploy application environments, a valuable skill in modern development workflows.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Thanks&lt;/strong&gt;&lt;br&gt;
The realization of this project owes much to Codecademy's "Back-End Engineer" course. Its comprehensive modules on Node.js, databases, and API design provided the knowledge foundation necessary to bring this project to life. This hands-on project reinforces theoretical learning and establishes a robust foundation in backend development, paving the way for more complex projects and deeper learning.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>backenddevelopment</category>
      <category>restapi</category>
      <category>learning</category>
    </item>
    <item>
      <title>Simplifying Authentication with JWT, TypeScript and Fastify</title>
      <dc:creator>Sreeharsha</dc:creator>
      <pubDate>Tue, 04 Jun 2024 04:54:23 +0000</pubDate>
      <link>https://dev.to/sraveend/simplifying-authentication-with-jwt-typescript-and-fastify-1dc9</link>
      <guid>https://dev.to/sraveend/simplifying-authentication-with-jwt-typescript-and-fastify-1dc9</guid>
      <description>&lt;p&gt;Authentication is the process of confirming the identity of a user, typically through credentials like a username and a password.&lt;br&gt;
Authorization, determines if a user is permitted to perform an action, once their identity is authenticated.&lt;/p&gt;

&lt;p&gt;JWT or JSON Web Token plays a crucial role in authentication and authorization process. It is an efficient and scalable solution for implementing secure authentication and authorization mechanisms in web applications. Learn more here: &lt;a href="https://jwt.io/introduction" rel="noopener noreferrer"&gt;JWT&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This article demonstrates a simple way to implement authentication using JWT with TypeScript and fastify. For the database, I have Postgres and Prisma as the ORM(Object Relational Mapper) tool.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Getting Started&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Follow the instructions provided in the github repository to setup the project: &lt;a href="https://github.com/sreeharsha-rav/typescript-projects/tree/main/auth-demo" rel="noopener noreferrer"&gt;auth-demo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highlights&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's always import to store passwords by encrypting them before writing them to the database. I have done it using &lt;code&gt;bcrypt&lt;/code&gt; and a simple salt value of 10 without any algorithm to hash the user password, during registration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/modules/user/user.controller.ts&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newUser&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;prismaClient&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;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="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;How to check the password during login? Since the salt value is private to the program, for any user request, the user can be authenticated by comparing the password with the encrypted password using &lt;code&gt;bcrypt&lt;/code&gt; as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/modules/user/user.controller.ts&lt;/span&gt;

&lt;span class="c1"&gt;// Compare the password&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isValidPassword&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's surprisingly quite simple to do a minimal secure authentication with JWT using &lt;code&gt;fastify-jwt&lt;/code&gt; plugin. This code in &lt;code&gt;index.ts&lt;/code&gt; registers the &lt;code&gt;fastify-jwt&lt;/code&gt; plugin with &lt;code&gt;secret&lt;/code&gt; . This &lt;code&gt;secret&lt;/code&gt; is used to sign and verify the JWTs. Ideally, for the most secure option you would generate a secret using an asymmetric algorithms like RS256, ES256 etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/index.ts&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fastifyJwt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;supersecret&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To generate a JWT token, once a valid user request for login comes through, the JWT toke is generate using a payload. In this program the payload is the user id and the username. You don't want to put the password in the payload because JWTs can be decoded.&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;// Generate a token&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;username&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;validTokens&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="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Store the token in the in-memory store&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I setup an in-memory store for valid tokens using a HashSet  for simplicity because it's a backend service. Ideally, would be managed on the client side. It enables the functionality of logging out, because of removing the appropriate token from the store. In &lt;code&gt;user.controller.ts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/modules/user/user.controller.ts&lt;/span&gt;

&lt;span class="c1"&gt;// In memory store to store the refresh tokens&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validTokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;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;// Remove the token from the in-memory store to logout user&lt;/span&gt;
&lt;span class="nx"&gt;validTokens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;To verify if the user is authenticated, it's a simple call from the &lt;code&gt;FastifyRequest&lt;/code&gt; in the controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// src/modules/user/user.controller.ts&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;jwtVerify&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Verify the JWT token&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, I added further checks to see if the authorization header is present along with token when authenticating user as well as during logging out for more control.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Further Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using JWT tokens provides a basic security to secure API endpoints, however with current trends in security, OAuth 2.0 and MFA is the standard.&lt;/p&gt;

&lt;p&gt;Storing tokens in-memory for logout functionality is a simple workaround for the backend. In practice, it would be the up to the frontend client application to manage and store JWT tokens to maintain User session.&lt;/p&gt;

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

&lt;p&gt;Authentication need not be complex for getting a proof of concept. With in-demand skills like Typescript and a simple framework like Fastify, you can streamline the process. This article provides a foundation for authentication in beginner applications.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>beginners</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Unlocking Code Reusability and Flexibility with Upcasting in Java</title>
      <dc:creator>Sreeharsha</dc:creator>
      <pubDate>Thu, 29 Feb 2024 00:29:27 +0000</pubDate>
      <link>https://dev.to/sraveend/unlocking-code-reusability-and-flexibility-with-upcasting-in-java-1c71</link>
      <guid>https://dev.to/sraveend/unlocking-code-reusability-and-flexibility-with-upcasting-in-java-1c71</guid>
      <description>&lt;p&gt;In Java programming, upcasting might seem like a cryptic concept, but its practical benefits are immense. Let's cut through the jargon and explore how upcasting can supercharge your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Upcasting?
&lt;/h3&gt;

&lt;p&gt;Upcasting allows you to treat a subclass instance as its superclass during compile-time, while preserving its true identity during runtime. Imagine you have a superclass &lt;code&gt;Noodle&lt;/code&gt; and a subclass &lt;code&gt;BiangBiang&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Noodle&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;lengthInCentimeters&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;widthInCentimeters&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;shape&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;ingredients&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;texture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"brittle"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="nc"&gt;Noodle&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;lenInCent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;wthInCent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;shp&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;ingr&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;lengthInCentimeters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;lenInCent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;widthInCentimeters&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;wthInCent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;shp&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ingredients&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ingr&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;cook&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;texture&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"cooked"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BiangBiang&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Noodle&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;BiangBiang&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;50.0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;5.0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"flat"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"high-gluten flour, salt, water"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dinner&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;makeNoodles&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Noodle&lt;/span&gt; &lt;span class="n"&gt;noodle&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sauce&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;noodle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cook&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mixing "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;noodle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;texture&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" noodles made from "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;noodle&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ingredients&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;" with "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sauce&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Dinner is served!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Dinner&lt;/span&gt; &lt;span class="n"&gt;noodlesDinner&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;Dinner&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="nc"&gt;Noodle&lt;/span&gt; &lt;span class="n"&gt;myNoodle&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;BiangBiang&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;noodlesDinner&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;makeNoodles&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myNoodle&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"soy sauce and chili oil"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Focus on this particular line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Noodle&lt;/span&gt; &lt;span class="n"&gt;myNoodle&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;BiangBiang&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;myNoodle&lt;/code&gt; is recognized as a &lt;code&gt;Noodle&lt;/code&gt; by the compiler, even though it's a &lt;code&gt;BiangBiang&lt;/code&gt; at runtime. This allows us to tap into &lt;code&gt;Noodle&lt;/code&gt;-specific features while enjoying the specialized behavior of &lt;code&gt;BiangBiang&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;For example, in Dinner class, the makeNoodles() method is called with the BiangBiang object and a sauce as arguments, resulting in the preparation of BiangBiang noodles for dinner.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Does it Matter?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Boosts Code Reusability:&lt;/strong&gt; With upcasting, you can use methods designed for the superclass (&lt;code&gt;Noodle&lt;/code&gt;) with its subclasses (&lt;code&gt;BiangBiang&lt;/code&gt;). No need to duplicate code or create separate methods for each subclass. It's a time-saver and keeps your codebase tidy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Enhances Flexibility:&lt;/strong&gt; By focusing on coding with superclasses, you gain the freedom to tweak functionality without affecting subclasses. Want to upgrade &lt;code&gt;Noodle&lt;/code&gt; behavior? No problem. It won't impact &lt;code&gt;BiangBiang&lt;/code&gt; or other subclasses. It's coding agility at its finest.&lt;/p&gt;

&lt;h3&gt;
  
  
  In Summary
&lt;/h3&gt;

&lt;p&gt;Upcasting is not just another OOP concept; it's a game-changer. It empowers developers to write cleaner, more adaptable code while minimizing redundancy. Look to embrace upcasting, and watch your codebase become more efficient and maintainable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Credits
&lt;/h3&gt;

&lt;p&gt;Dinner, Noodle, BiangBiang code from codecademy.&lt;/p&gt;

&lt;p&gt;Whoever thought about the idea of upcasting is a genius!&lt;/p&gt;

</description>
      <category>java</category>
      <category>oop</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
