<?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: bytebantz</title>
    <description>The latest articles on DEV Community by bytebantz (@bytebantz).</description>
    <link>https://dev.to/bytebantz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1409089%2F1a1af1b7-a5de-4c5c-8b1d-f37f64806d10.jpeg</url>
      <title>DEV Community: bytebantz</title>
      <link>https://dev.to/bytebantz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bytebantz"/>
    <language>en</language>
    <item>
      <title>The Most Confused Concepts in Agentic AI</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Mon, 26 Oct 2026 15:46:49 +0000</pubDate>
      <link>https://dev.to/bytebantz/the-most-confused-concepts-in-agentic-ai-3h4j</link>
      <guid>https://dev.to/bytebantz/the-most-confused-concepts-in-agentic-ai-3h4j</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://medium.com/ai-tools-digest/the-most-confused-concepts-in-agentic-ai-e2a7507211c4" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In this article we are going to cover 4 commonly confused concepts in agentic AI.&lt;/p&gt;

&lt;p&gt;Understanding these distinctions will help you avoid confusing LLM-powered workflows with AI agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Using an LLM doesn’t make a system an AI Agent.
&lt;/h2&gt;

&lt;p&gt;What makes a system an AI Agent is the LLM’s role in deciding and directing the execution process, not simply whether the system uses an LLM.&lt;/p&gt;

&lt;p&gt;To understand why, we are going to distinguish between an agentic workflow and an AI agent.&lt;/p&gt;

&lt;p&gt;Both fall under Agentic AI.&lt;/p&gt;

&lt;p&gt;The difference is how much control the LLM has over the execution process.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Agentic Workflow
&lt;/h3&gt;

&lt;p&gt;An agentic workflow is an AI system where the developer defines the execution path in advance, and the LLM cannot modify or redesign that path.&lt;/p&gt;

&lt;p&gt;However, the LLM may make decisions within the execution process, such as classifying user intent or generating a response, but the surrounding code controls how those steps are connected and executed.&lt;/p&gt;

&lt;p&gt;Example: “What is the price of an iPhone 15?”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User message
     ↓
Classify intent        ← LLM identifies "get_product_price"
     ↓
Price node             ← Code retrieves the price
     ↓
Response node          ← LLM generates the reply
     ↓
"The iPhone 15 costs $1000."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. AI Agent
&lt;/h3&gt;

&lt;p&gt;An AI agent is an AI system where the LLM dynamically decides which steps to take, which tools to use, and whether to continue, based on the task and the results it observes.&lt;/p&gt;

&lt;p&gt;Unlike a workflow, the LLM can determine and adjust its own execution path.&lt;/p&gt;

&lt;p&gt;Example: “I want the black iPhone, the newer one, if it’s in stock.”&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User message
     ↓
Agent (LLM) decides to search for the product
     ↓
Calls search_products("black iPhone")
     ↓
Receives: iPhone 14, iPhone 15, iPhone 15 Pro
     ↓
Agent decides to check the latest model first
     ↓
Calls check_stock("iPhone 15 Pro", color="black")
     ↓
Receives: Out of stock
     ↓
Agent decides to check another suitable model
     ↓
Calls check_stock("iPhone 15", color="black")
     ↓
Receives: 12 in stock
     ↓
Agent decides it has enough information
     ↓
Responds to the user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, the LLM determines which tool to call next based on the user’s request and the results returned by previous tool calls.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. All agents are agentic AI, but not all agentic AI systems are agents.
&lt;/h2&gt;

&lt;p&gt;The word agentic AI sounds like it means “has an agent in it.”&lt;/p&gt;

&lt;p&gt;So people assume any agentic AI system is an agent.&lt;/p&gt;

&lt;p&gt;An agentic AI system is a system where an LLM’s decisions influence what the system does, either within steps defined by the developer (a workflow) or by dynamically directing the steps itself (an agent).&lt;/p&gt;

&lt;p&gt;There are two common ways to design an agentic AI system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Agentic Workflow: The developer defines the execution path.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AI Agent: The LLM dynamically decides which actions to take next based on the task and the results of previous actions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both can be considered agentic AI systems under this broad definition, although terminology varies across sources.&lt;/p&gt;

&lt;p&gt;For example, a LangGraph workflow that uses an LLM to classify a request and routes it through developer-defined steps is an agentic AI system, but not necessarily an AI agent.&lt;/p&gt;

&lt;p&gt;A LangGraph agent that uses an LLM to dynamically choose tools, observe their results, and decide what to do next is both an AI agent and an agentic AI system.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. An agent is a loop, not a single call
&lt;/h2&gt;

&lt;p&gt;An AI agent doesn’t simply call an LLM once and finish.&lt;/p&gt;

&lt;p&gt;It repeatedly makes decisions, takes actions, observes the results, and decides what to do next until it considers the task complete.&lt;/p&gt;

&lt;p&gt;An agent uses the result of one step to determine its next step.&lt;/p&gt;

&lt;p&gt;The loop is what allows an agent to handle tasks that require multiple actions, respond to unexpected results, and correct its approach along the way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic agent loop
&lt;/h3&gt;

&lt;p&gt;Press enter or click to view image in full size&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Decide: The LLM looks at the request and everything it knows so far, and picks the next action.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Act: The agent uses a tool to carry out that action.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Observe: The tool’s result is added to the agent’s context as new information.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Decide again: The LLM uses the new information to determine what should happen next. It might call another tool, repeat an earlier action, or conclude that the task is finished.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The loop ends when the LLM gives a final answer instead of calling a tool, or when it hits a limit you set, like a maximum number of turns or an error it can’t recover from.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Tool calling alone doesn’t make a system an agent.
&lt;/h2&gt;

&lt;p&gt;Tool calling is a capability that allows an LLM to call an external function or API to perform an action.&lt;/p&gt;

&lt;p&gt;What determines whether the system behaves as an agent is what or who controls the decisions surrounding that tool call.&lt;/p&gt;

&lt;p&gt;If the developer decides when a tool runs and what happens after, it’s still a workflow.&lt;/p&gt;

&lt;p&gt;It becomes an agent when the LLM decides whether to call the tool, which tool to call, and what to do with the result.&lt;/p&gt;

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

&lt;p&gt;In conclusion, understanding the difference between AI agents and agentic workflows comes down to who controls execution.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>softwareengineering</category>
      <category>programming</category>
    </item>
    <item>
      <title>Mastering Datadog AI Agent Observability: A Beginners Guide</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Fri, 23 Oct 2026 06:21:05 +0000</pubDate>
      <link>https://dev.to/bytebantz/mastering-datadog-ai-agent-observability-a-beginners-guide-ig2</link>
      <guid>https://dev.to/bytebantz/mastering-datadog-ai-agent-observability-a-beginners-guide-ig2</guid>
      <description>&lt;h1&gt;
  
  
  Agent Observability Is a Must-Have for LLM Applications
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://medium.com/javascript-in-plain-english/mastering-datadog-ai-agent-observability-a-beginners-guide-cab7f8bbb5fd" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When something goes wrong, identifying the actual cause isn’t always straightforward due to non-deterministic nature of LLM applications.&lt;/p&gt;

&lt;p&gt;Adding logs helps, but logs alone often aren’t enough for LLM applications.&lt;/p&gt;

&lt;p&gt;You might have no visibility of the complete workflow if you are using logs alone.&lt;/p&gt;

&lt;p&gt;This is where Datadog Agent Observability comes in.&lt;/p&gt;

&lt;p&gt;Datadog gives you end-to-end visibility into your AI application’s execution.&lt;/p&gt;

&lt;p&gt;Instead of guessing what happened, you can trace a user’s request through out the complete execution flow.&lt;/p&gt;

&lt;p&gt;Implementing Datadog agent observability involves 3 core components:&lt;/p&gt;

&lt;p&gt;⚪ Traces — shows the complete journey of a single request.&lt;/p&gt;

&lt;p&gt;⚪🟡 Spans — represent individual operations within a trace.&lt;/p&gt;

&lt;p&gt;⚪🟡⚪ Instrumentation is the process of capturing this information automatically or manually and sending it to Datadog for analysis.&lt;/p&gt;

&lt;p&gt;Press enter or click to view image in full size&lt;/p&gt;

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

&lt;p&gt;A trace represents the complete execution path of a single request handled by the LLM application.&lt;/p&gt;

&lt;p&gt;A trace captures everything that happens while the application processes that request, including LLM calls, agent decisions, tool calls, and other operations.&lt;/p&gt;

&lt;p&gt;A trace can contain multiple spans, where each span represents an individual operation within the overall request.&lt;/p&gt;

&lt;h3&gt;
  
  
  LLM Agent workflow
&lt;/h3&gt;

&lt;p&gt;An agent trace groups together all workflows and contextual operations such as the tool calls and reasoning steps executed by an agent to complete a user request.&lt;/p&gt;

&lt;p&gt;For example, a user asks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"What's the weather in Nairobi?"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI agent might:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Receive the user’s request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Call an LLM to determine what to do.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Call a weather tool.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send the weather data back to the LLM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Generate the final response.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;All of these operations can be represented within the same trace.&lt;/p&gt;

&lt;h3&gt;
  
  
  Trace Structure Example:
&lt;/h3&gt;

&lt;p&gt;Press enter or click to view image in full size&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TRACE
────────────────────────────────
trace_id: trace_001
────────────────────────────────

Agent / Workflow Span
span_id: span_001
trace_id: trace_001
│
├── LLM Span
│   span_id: span_002
│   trace_id: trace_001
│
│   Input:
│   "What's the weather in Nairobi?"
│
│   Output:
│   "I need to check the weather."
│
├── Tool Span
│   span_id: span_003
│   trace_id: trace_001
│
│   Input:
│   {
│     "location": "Nairobi"
│   }
│
│   Output:
│   {
│     "temperature": 23,
│     "condition": "Partly cloudy"
│   }
│
└── LLM Span
    span_id: span_004
    trace_id: trace_001

    Input:
    Weather data from tool

    Output:
    "It's 23°C and partly cloudy in Nairobi."

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  TRACE SAMPLING
&lt;/h3&gt;

&lt;p&gt;Trace Sampling is a method datadog uses to determine the number of traces to retain for observability.&lt;/p&gt;

&lt;p&gt;Agent Observability billing is based on the volume of spans sent.&lt;/p&gt;

&lt;p&gt;Setting a sample rate is a direct way to control the cost for agent obervability.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Suppose your application receives:
10,000 agent requests


And each request generates approximately:
10 spans

You could therefore send to DataDog approximately:
10,000 × 10 = 100,000 spans
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since Agent Observability billing is based on the volume of spans sent, this can become expensive at scale.&lt;/p&gt;

&lt;p&gt;This is where trace sampling comes in.&lt;/p&gt;

&lt;p&gt;You can configure the sample rate (a float between 0.0 and 1.0)&lt;/p&gt;

&lt;h4&gt;
  
  
  SETTING A SAMPLE RATE
&lt;/h4&gt;

&lt;p&gt;Suppose we configure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sample rate = 0.5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above sample rate means approximately 50% of traces (50,000) will be retained instead of 100,000.&lt;/p&gt;

&lt;p&gt;While trace sampling allows you to control the ingestion volume and storage costs for your individual traces and spans, it does not impact these operational metrics&lt;/p&gt;

&lt;p&gt;Such metrics includes:&lt;/p&gt;

&lt;p&gt;🟡 Token metrics&lt;/p&gt;

&lt;p&gt;🟡🟡 Cost metrics&lt;/p&gt;

&lt;p&gt;🟡🟡🟡 Performance metrics&lt;/p&gt;

&lt;p&gt;Press enter or click to view image in full size&lt;/p&gt;

&lt;h2&gt;
  
  
  2. SPAN
&lt;/h2&gt;

&lt;p&gt;A span represents a single operation in a trace.&lt;/p&gt;

&lt;p&gt;A span serves as the fundamental building block of a trace&lt;/p&gt;

&lt;p&gt;Press enter or click to view image in full size&lt;/p&gt;

&lt;h3&gt;
  
  
  1. SPAN ATTRIBUTES
&lt;/h3&gt;

&lt;p&gt;A span attribute describes the operation represented by the span.&lt;/p&gt;

&lt;p&gt;Span attributes represent the content of the work being done within the span&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
Suppose the span represents this operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The span could contain the following span attributes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@db.system:postgres
@db.operation:SELECT
@db.table:users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  WHERE DO SPAN ATTRIBUTES COME FROM?
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Automatic instrumentation
&lt;/h5&gt;

&lt;p&gt;Datadog’s APM libraries can automatically collect information.&lt;/p&gt;

&lt;p&gt;This means there is no need to write code to record values for such fields.&lt;/p&gt;

&lt;p&gt;For example, your application makes an HTTP request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /products
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The instrumentation may automatically record things like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apiblueprint"&gt;&lt;code&gt;&lt;span class="nv"&gt;@http.method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;
&lt;span class="nv"&gt;@http.route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s"&gt;/products&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  2. Manual/custom instrumentation
&lt;/h5&gt;

&lt;p&gt;This means we have to explicitly specify the fields to record.&lt;/p&gt;

&lt;p&gt;This is useful because it allows you to put business-specific information into your traces.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
Suppose your application calculates the shopping cart value:&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;cart_total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1299.99&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might instrument your application so the span contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@cart.total:1299.99
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddtrace&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;

&lt;span class="c1"&gt;# Get the current active span
&lt;/span&gt;&lt;span class="n"&gt;span&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tracer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current_span&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Manually set a custom attribute
&lt;/span&gt;    &lt;span class="n"&gt;span&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_tag&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;cart.total&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1299.99&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  RESERVED SPAN ATTRIBUTES
&lt;/h4&gt;

&lt;p&gt;Datadog has certain reserved span attributes&lt;/p&gt;

&lt;p&gt;Reserved span attributes are automatically instrumented and are available on every span.&lt;/p&gt;

&lt;p&gt;You do not need to perform any manual setup to ensure these attributes are collected for your traces:&lt;/p&gt;

&lt;p&gt;env: environment name (e.g. production) where the service is running.&lt;/p&gt;

&lt;p&gt;service: The name of the service that generated the span.&lt;/p&gt;

&lt;p&gt;operation_name: The specific name of the operation being performed.&lt;/p&gt;

&lt;p&gt;resource_name: A human-readable name for the resource associated with the operation (e.g., an endpoint path or a database query).&lt;/p&gt;

&lt;p&gt;status: The operational status of the span (e.g., ok or error).&lt;/p&gt;

&lt;p&gt;span_id: The unique identifier for that specific span.&lt;/p&gt;

&lt;p&gt;trace_id: The unique identifier that groups all spans belonging to the same request or workflow.&lt;/p&gt;

&lt;p&gt;timestamp: The exact time the span occurred.&lt;/p&gt;

&lt;p&gt;type: The category of operation (e.g., web, db, or cache).&lt;/p&gt;

&lt;p&gt;link: References connecting the span to other spans or traces.&lt;/p&gt;

&lt;p&gt;ingestion_reason: The reason why the trace or span was retained by the Datadog ingestion pipeline.&lt;/p&gt;

&lt;p&gt;When working with reserved attributes, don’t put @ in front.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;service:checkout&lt;/span&gt;
&lt;span class="s"&gt;env:production&lt;/span&gt;
&lt;span class="s"&gt;status:error&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@service:checkout
@env:production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. SPAN TAGS
&lt;/h3&gt;

&lt;p&gt;Span tags are contextual information about where the span came from for example infrastructure/environment context.&lt;/p&gt;

&lt;p&gt;Tags don’t require @.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;hostname:web-server-17&lt;/span&gt;
&lt;span class="s"&gt;availability-zone:us-east-1a&lt;/span&gt;
&lt;span class="s"&gt;cluster-name:production-cluster&lt;/span&gt;
&lt;span class="s"&gt;container_name:api-frontend&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These tags provide context about the infrastructure or orchestration environment where the service is running&lt;/p&gt;

&lt;h3&gt;
  
  
  3. ANNOTATIONS
&lt;/h3&gt;

&lt;p&gt;Annotations are additional pieces of context that you can attach to a span to make the trace more useful for analysis.&lt;/p&gt;

&lt;p&gt;Annotations describe business-specific context about an operation.&lt;/p&gt;

&lt;p&gt;This helps explain operations from a business perspective.&lt;/p&gt;

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

&lt;p&gt;A checkout span could have annotations like customer_tier=premium or order_type=subscription.&lt;/p&gt;

&lt;p&gt;Spans automatically capture common information such as: duration, status, errors, input, output&lt;/p&gt;

&lt;p&gt;But sometimes you want to add your own context.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
Suppose you’re building a customer-support AI.&lt;/p&gt;

&lt;p&gt;You may want to know additional information about each request, such as:&lt;/p&gt;

&lt;p&gt;In Datadog, annotations are filtered using attribute search syntax, where attributes are prefixed with an @ symbol.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@customer_tier:premium 
@language:en 
@ticket_category:refund 
@department:electronics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using ddtrace, you can attach this business context to the current span with LLMObs.annotate():&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddtrace.llmobs&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LLMObs&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddtrace.llmobs.decorators&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_support_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;process_support_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;LLMObs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;annotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;tags&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;customer_tier&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;premium&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;language&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;en&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;ticket_category&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;refund&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;department&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;electronics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The resulting span now contains both its normal observability information and your additional business context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tool Span: handle_support_request
────────────────────────────────────────
Duration:
    4.2 sec
Status:
    OK
Input:
    "I want a refund for my headphones."
Output:
    "I'll help you process your refund..."
Annotations:
    customer_tier:   premium
    language:        en
    ticket_category: refund
    department:      electronics
────────────────────────────────────────
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using annotations, allow you to filter, group, and analyze traces based on your application’s specific business context.&lt;/p&gt;

&lt;p&gt;For example, you could filter traces where:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@customer_tier:premium
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to investigate premium-customer requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  SPANS CATEGORIZATION
&lt;/h3&gt;

&lt;p&gt;Datadog allows spans to be categorized according to the type of operation they represent.&lt;/p&gt;

&lt;p&gt;Instead of representing every operation as a generic span (Span), Datadog allows spans to be categorized according to the type of operation they represent:&lt;/p&gt;

&lt;p&gt;Categorizing spans makes your traces:&lt;/p&gt;

&lt;p&gt;🟢- Easier to understand&lt;/p&gt;

&lt;p&gt;🟢🟢- Easier to troubleshoot&lt;/p&gt;

&lt;p&gt;🟢🟢🟢- Easier to analyze&lt;/p&gt;

&lt;p&gt;Press enter or click to view image in full size&lt;/p&gt;

&lt;h3&gt;
  
  
  TYPES OF SPANS
&lt;/h3&gt;

&lt;p&gt;Press enter or click to view image in full size&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Agent Span
&lt;/h4&gt;

&lt;p&gt;An Agent is an AI system that can decide what actions it needs to take and in what order to accomplish a goal.&lt;/p&gt;

&lt;p&gt;An Agent span represents the complete execution of an AI agent.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
Consider a travel-planning agent that helps a user plan a trip.&lt;/p&gt;

&lt;p&gt;The agent can be implemented as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddtrace.llmobs.decorators&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;# Define tools
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_flights&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Tool execution logic
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_hotels&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Tool execution logic
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Tool execution logic
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="nd"&gt;@agent&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;plan_trip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# The LLM analyzes the request and decides which tools to use
&lt;/span&gt;    &lt;span class="n"&gt;llm_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;completions&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="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;messages&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;role&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;user&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&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;customer_query&lt;/span&gt;&lt;span class="p"&gt;}],&lt;/span&gt;
        &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="n"&gt;search_flights&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;search_hotels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;check_weather&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="n"&gt;llm_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Root Span
&lt;/h4&gt;

&lt;p&gt;A root span is defined by its position in the trace hierarchy.&lt;/p&gt;

&lt;p&gt;A span is considered a root span, if it is the span at the very top, with no parent span.&lt;/p&gt;

&lt;p&gt;An agent span may be the root span, particularly when the agent execution is the top-level operation you’re tracing.&lt;/p&gt;

&lt;p&gt;But if the agent is itself invoked by another operation — such as a workflow — it can be a child span.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;travel_workflow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;validate_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;plan_trip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;save_itinerary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Workflow complete&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conceptually, the trace looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ROOT SPAN: travel_workflow
│
├── Span: validate_request
│
├── Agent Span: plan_trip
│   │
│   ├── LLM Span: understand_requirements
│   │
│   ├── Tool Span: search_flights
│   │
│   ├── Tool Span: search_hotels
│   │
│   ├── LLM Span: compare_options
│   │
│   ├── Tool Span: check_weather
│   │
│   └── LLM Span: generate_itinerary
│
└── Span: save_itinerary
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Workflow Span
&lt;/h4&gt;

&lt;p&gt;A workflow span represents the execution of a complete, high-level process within an application.&lt;/p&gt;

&lt;p&gt;A workflow in Agents Observability is a predefined sequence of operations that may include LLM calls, tool calls, data processing, and other steps required to complete a task.&lt;/p&gt;

&lt;p&gt;A Workflow Span represents the complete execution of the workflow.&lt;/p&gt;

&lt;p&gt;Unlike an Agent, which can autonomously decide which actions to take, a workflow generally follows a predefined sequence of operations defined by the application.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
Consider a customer support ticket workflow:&lt;/p&gt;

&lt;p&gt;The workflow can be implemented using the @workflow decorator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddtrace.llmobs.decorators&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;workflow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;retrieval&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retrieve_customer_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Logic to fetch customer information from an external database
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="nd"&gt;@llm&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;classify_ticket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# LLM call to categorize the support ticket
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="nd"&gt;@retrieval&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_knowledge_base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Logic to search a vector database or external KB
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="nd"&gt;@llm&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;knowledge&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# LLM call to generate the ticket response
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="nd"&gt;@task&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;send_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Logic to format/send the response (no external call)
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;

&lt;span class="nd"&gt;@workflow&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_support_ticket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;customer_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;retrieve_customer_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ticket_category&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;classify_ticket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;knowledge&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;search_knowledge_base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticket_category&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ticket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer_data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;knowledge&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;send_response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Task Span
&lt;/h4&gt;

&lt;p&gt;A task span represents an individual processing operation performed by an application that don’t call an external service.&lt;/p&gt;

&lt;p&gt;It is typically used for application-level logic that happens within the application itself, rather than an operation that calls an external service.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
Consider an application that calculates a discount for a customer.&lt;/p&gt;

&lt;p&gt;The task can be implemented using the @task decorator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddtrace.llmobs.decorators&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;

&lt;span class="nd"&gt;@task&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_discount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;customer_type&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;customer_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;premium&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.80&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. LLM Span
&lt;/h4&gt;

&lt;p&gt;An LLM span represents an LLM call.&lt;/p&gt;

&lt;p&gt;It captures the model invocation, including the model used, input, output, token usage, latency, and status.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddtrace.llmobs.decorators&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;

&lt;span class="nd"&gt;@llm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpt-4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# model_name is optional
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_product_description&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Generate description for: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;product_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above example could be represented as:&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Tool Span
&lt;/h4&gt;

&lt;p&gt;A tool represents calls to external services like databases, APIs made by an AI application.&lt;/p&gt;

&lt;p&gt;A tool span represents the details of the external operation, such as what tool was called, the input provided, the result returned, and how long the operation took.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
Consider an AI customer-support assistant, that calls an external API to fetch order details:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddtrace.llmobs.decorators&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;

&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_inventory_status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;inventory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT quantity, location FROM inventory WHERE product_id = ?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;product_id&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;inventory&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  7. Embedding span
&lt;/h4&gt;

&lt;p&gt;An Embedding Span represents the operation of converting text or other data into an embedding vector using an embedding model.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddtrace.llmobs.decorators&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;embedding&lt;/span&gt;

&lt;span class="nd"&gt;@embedding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text-embedding-ada-002&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# model_name is required, model_provider is optional
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_product_embedding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_text&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;embedding_model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tolist&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  8. Retrieval Span
&lt;/h4&gt;

&lt;p&gt;A retrieval span represents the operation of searching for and retrieving relevant information from a data source, such as a vector database.&lt;/p&gt;

&lt;p&gt;The retrieval span captures the search operation and the information returned by it.&lt;/p&gt;

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

&lt;p&gt;For example, in an AI shopping assistant, a user might ask:&lt;/p&gt;

&lt;p&gt;“Find me a black running shoe under $100.”&lt;/p&gt;

&lt;p&gt;The retrieval operation can be instrumented using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;ddtrace.llmobs.decorators&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;retrieval&lt;/span&gt;

&lt;span class="nd"&gt;@retrieval&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_product_catalog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;query_vector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate_embedding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vector_db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;similarity_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_vector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;Agent observability helps you see what happens inside your AI application when it processes a request.&lt;/p&gt;

&lt;p&gt;Datadog uses traces, spans, and instrumentation to help you follow a request from beginning to end, inspect individual steps, and find out why something failed or took too long.&lt;/p&gt;

&lt;p&gt;Logs are useful, but observability gives you a clearer picture of how the different parts of your application work together.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Full Jev Tutorial for Beginners</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Fri, 23 Oct 2026 06:17:27 +0000</pubDate>
      <link>https://dev.to/bytebantz/full-jev-tutorial-for-beginners-16gc</link>
      <guid>https://dev.to/bytebantz/full-jev-tutorial-for-beginners-16gc</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://medium.com/gitconnected/jev-explained-200x-faster-400x-cheaper-a7571426669d" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Jev is an AI model created by Diogo Almeida who co-invented ChatGPT.&lt;/p&gt;

&lt;p&gt;Jev is apparently 200x faster and 400x cheaper than regular AI models.&lt;/p&gt;

&lt;p&gt;But what makes Jev interesting isn’t just its speed or cost. It’s how it approaches AI.&lt;/p&gt;

&lt;p&gt;Jev is built for software, not humans.&lt;/p&gt;

&lt;p&gt;This means Jev is designed to return decisions that an application can act on directly, rather than text responses written for a person to read.&lt;/p&gt;

&lt;p&gt;A general-purpose LLM can understand language, extract information, reason about problems, generate content, and transform unstructured input into structured output.&lt;/p&gt;

&lt;p&gt;But in most cases, your application might only need a specific decision.&lt;/p&gt;

&lt;p&gt;Imagine a customer support system that needs to determine which team should handle a complaint.&lt;/p&gt;

&lt;p&gt;With a conventional LLM, you might prompt it to return JSON containing the team name. Your application then parses the response and extracts the decision.&lt;/p&gt;

&lt;p&gt;Jev approaches the task differently.&lt;/p&gt;

&lt;p&gt;You define the decisions your application needs, the accepted answer types, and the criteria for evaluating each answer.&lt;/p&gt;

&lt;p&gt;Jev then returns structured decision results that your application can act on directly.&lt;/p&gt;

&lt;p&gt;Instead of generating text that describes a decision, Jev is designed to return the decision itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use Case Example:
&lt;/h2&gt;

&lt;p&gt;Imagine you work at an online shop. Customers send complaints like these:&lt;/p&gt;

&lt;p&gt;Press enter or click to view image in full size&lt;/p&gt;

&lt;p&gt;You don’t want an employee to read every complaint and decide what happens next.&lt;/p&gt;

&lt;p&gt;Jev helps your application do some of that work automatically and make decisions from the customer’s message.&lt;/p&gt;

&lt;p&gt;Instead of writing a text response like most general LLMs explaining the complaint, Jev returns structured decisions that your application can use.&lt;/p&gt;

&lt;p&gt;Press enter or click to view image in full size&lt;/p&gt;

&lt;p&gt;When making a decision with Jev, you are required to provide 2 things:&lt;/p&gt;

&lt;p&gt;🟡 State — the information Jev should evaluate.&lt;/p&gt;

&lt;p&gt;🟡 🟡 Questions — the decisions you want Jev to make about that information.&lt;/p&gt;

&lt;p&gt;Each question has 3 main parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;type: the kind of answer you expect.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;instructions: what you want Jev to determine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;criteria: how to interpret the possible answers.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"questions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"is_bug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"noul"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"instructions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Is the customer reporting a software defect?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"criteria"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The customer describes broken or unexpected product behavior."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The customer is asking a question or requesting a feature."&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 1: Give Jev the customer’s complaint
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"state"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"customer_tier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"enterprise"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ticket"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"My checkout page shows a blank screen after I click Pay. I have tried two browsers."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of state as a box containing information about the problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Ask Jev the first question — is it a bug?
&lt;/h3&gt;

&lt;p&gt;Your application needs to know whether the customer is reporting a software defect.&lt;/p&gt;

&lt;p&gt;To help Jev determine exactly counts as a bug, you provide criteria:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"criteria"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The customer describes broken or unexpected product behavior."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"false"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The customer is asking a question or requesting a feature."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Ask Jev the second question — which team should handle it?
&lt;/h3&gt;

&lt;p&gt;Knowing that something is broken isn’t enough.&lt;/p&gt;

&lt;p&gt;Your company may have different teams:&lt;/p&gt;

&lt;p&gt;🔴Payments team&lt;/p&gt;

&lt;p&gt;🟠Frontend team&lt;/p&gt;

&lt;p&gt;🟡Account team&lt;/p&gt;

&lt;p&gt;You need Jev to select one of them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"criteria"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"payments"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Checkout, billing, or payment processing issues."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"frontend"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Rendering, layout, or browser compatibility issues."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"account"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Login, permissions, or profile issues."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Complete implementation
&lt;/h2&gt;

&lt;p&gt;You don’t need to make one request to determine whether the complaint describes a bug and another to identify the responsible team.&lt;/p&gt;

&lt;p&gt;Both questions can be sent in the same request.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jev-demo/
├── triage.py          the demo
├── requirements.txt   one dependency: requests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;You need Python 3.9 or newer and an OpenRouter API key from &lt;a href="https://openrouter.ai/settings/keys" rel="noopener noreferrer"&gt;https://openrouter.ai/settings/keys&lt;/a&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a virtual environment and install the dependency&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;macOS / Linux&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;jev-demo
python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv .venv
&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Windows (PowerShell):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;jev-demo&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;venv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;venv&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;venv&lt;/span&gt;&lt;span class="nx"&gt;\Scripts\Activate.ps1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;pip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;requirements.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Set your API key&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;macOS / Linux:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENROUTER_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sk-or-...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Windows (PowerShell):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$&lt;/span&gt;&lt;span class="nn"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nv"&gt;OPENROUTER_API_KEY&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sk-or-..."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run ▶
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python triage.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What Jev might return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Bug&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;probability:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.96&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Team:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;payments&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(confidence&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.72&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;payments:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.81&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;frontend:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.19&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;account:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.00&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Decision:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;bug&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;route&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;payments&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;team&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Types in Jev
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Types Supported by Jev
&lt;/h3&gt;

&lt;p&gt;A type tells Jev what kind of answer you want it to produce.&lt;/p&gt;

&lt;p&gt;Press enter or click to view image in full size&lt;/p&gt;

&lt;h4&gt;
  
  
  ⚪ Noul — Yes or no
&lt;/h4&gt;

&lt;p&gt;Use it when your question requires a boolean response.&lt;/p&gt;

&lt;p&gt;Example: Is this complaint reporting a software bug?&lt;/p&gt;

&lt;h4&gt;
  
  
  ⚪ 🟡 Choice — Select an option
&lt;/h4&gt;

&lt;p&gt;Use it when your question has several possible answers and you want one selected.&lt;/p&gt;

&lt;p&gt;Example: Which team should handle the complaint?&lt;/p&gt;

&lt;h4&gt;
  
  
  ⚪ 🟡⚪ Score — An ordered scale
&lt;/h4&gt;

&lt;p&gt;Use it when your question asks for a position on a scale with ordered criteria.&lt;/p&gt;

&lt;p&gt;Example: How urgent is the complaint?&lt;/p&gt;

&lt;h2&gt;
  
  
  Knowledge Check
&lt;/h2&gt;

&lt;p&gt;Press enter or click to view image in full size&lt;/p&gt;

&lt;h2&gt;
  
  
  LLM + Jev NOT LLM vs Jev
&lt;/h2&gt;

&lt;p&gt;In an e-commerce AI agent, when an LLM is the reasoning engine of your agent, one call usually does two jobs.&lt;/p&gt;

&lt;p&gt;It extracts the entities, and it decides what the user wants (intent).&lt;/p&gt;

&lt;p&gt;In the following example we ask for both entities and intent in one JSON response:&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;system_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
&lt;/span&gt;&lt;span class="gp"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;Return&lt;/span&gt; &lt;span class="n"&gt;ONLY&lt;/span&gt; &lt;span class="n"&gt;JSON&lt;/span&gt; &lt;span class="n"&gt;matching&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;exact&lt;/span&gt; &lt;span class="n"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;reasoning&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;Short explanation of what was detected.&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;entities&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;product_names&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;item name 1&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;item name 2&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;quantity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;        &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;color&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;red&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;size&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;10&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cart_action&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;add&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;modify&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;view&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;list_categories&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;list_orders&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;     &lt;span class="n"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;checkout_intent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;false&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="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using an LLM alone for both jobs is prone to errors.&lt;/p&gt;

&lt;p&gt;For example the model might return:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"product_names"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Nike shoes"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"quantity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cart_action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"add_to_cart"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your application expects “add”, but the model returns “add_to_cart”.&lt;/p&gt;

&lt;p&gt;The meaning is clear to a human, but your code might reject the value because it is not the expected value.&lt;/p&gt;

&lt;p&gt;Instead, use the LLM for entity extraction and Jev for decision-making.&lt;/p&gt;

&lt;p&gt;Instead of asking the LLM to extract entities and decide the user’s intent in one JSON response, let it extract only the entities:&lt;/p&gt;

&lt;p&gt;However you still parse and validate the LLM’s JSON, but it is now a smaller response that holds only entities.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"product_names"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"item name 1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"item name 2"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"quantity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"color"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="s2"&gt;"red"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"size"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="s2"&gt;"10"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jev then handles the decisions by evaluating the message against predefined options and returning probabilities for each choice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"questions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"intent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"choice"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"instructions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"What does the shopper want to do?"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"criteria"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"add_to_cart"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="s2"&gt;"Wants to add a product to the cart."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"modify_cart"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="s2"&gt;"Wants to change or remove something in the cart."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"view_cart"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="s2"&gt;"Wants to see the cart."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"checkout"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="s2"&gt;"Wants to check out or pay."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"list_orders"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="s2"&gt;"Wants to see past orders."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"list_categories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Wants to see the product categories."&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press enter or click to view image in full size&lt;/p&gt;

&lt;p&gt;If Jev runs first and identifies an intent that requires no entity extraction, such as view_cart, checkout, or list_orders, you can skip the LLM call entirely for that turn.&lt;/p&gt;

&lt;p&gt;This means you save on:&lt;/p&gt;

&lt;p&gt;🟡LLM API costs: No charge for an unnecessary model call.&lt;/p&gt;

&lt;p&gt;🟡Latency: The user doesn’t have to wait for the LLM to extract entities that are not needed.&lt;/p&gt;

&lt;p&gt;🟡Token usage: No input or output tokens spent on that LLM call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Jev vs. ML Classifiers (Random Forest)
&lt;/h2&gt;

&lt;p&gt;A classifier basically is a system that takes something as input and assigns it to a category.&lt;/p&gt;

&lt;p&gt;A random forest and Jev can both look at a customer’s message and pick an intent: add_to_cart, view_cart, checkout or list_orders.&lt;/p&gt;

&lt;p&gt;Both choose from a fixed set of answers, both return probabilities, and neither writes text.&lt;/p&gt;

&lt;p&gt;Press enter or click to view image in full size&lt;/p&gt;

&lt;p&gt;For Random Forest, you have to provide examples and answers, train the model, and use the resulting model for its learned task.&lt;/p&gt;

&lt;p&gt;For instance, if you provide many messages labeled checkout. The model learns patterns from those examples and uses them to classify new messages.&lt;/p&gt;

&lt;p&gt;However, if the task changes substantially, you may need to train another model.&lt;/p&gt;

&lt;p&gt;For Jev, TypeSafe has already trained the general model.&lt;/p&gt;

&lt;p&gt;You just have to describe the task and its possible answers in plain English when you make a request.&lt;/p&gt;

&lt;p&gt;If the task changes, you can usually change the question and options instead of training a new model.&lt;/p&gt;

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

&lt;p&gt;JEV is not trying to replace general LLM models such as GPT, Gemini or Claude.&lt;/p&gt;

&lt;p&gt;JEV is built to generate decisions.&lt;/p&gt;

&lt;p&gt;Use JEV when your app needs to choose and LLMs when you need to generate text responses.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>webdev</category>
    </item>
    <item>
      <title>PHP Got Hacked by AI</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Fri, 23 Oct 2026 06:01:41 +0000</pubDate>
      <link>https://dev.to/bytebantz/php-got-hacked-by-ai-1ema</link>
      <guid>https://dev.to/bytebantz/php-got-hacked-by-ai-1ema</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://medium.com/ai-tools-digest/php-got-hacked-by-ai-f307388bec7a" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At 9:55 p.m. on Wednesday, October 21, 2026, in Tokyo, Japan, the prime minister Sanae Takaichi urged website owners to check whether they ran PHP and apply a security fix as soon as it became available.&lt;/p&gt;

&lt;p&gt;If they couldn’t patch, she advised temporarily disabling parts of their sites.&lt;/p&gt;

&lt;p&gt;About an hour later, PHP released fixes for two critical vulnerabilities.&lt;/p&gt;

&lt;p&gt;The US National Security Agency issued an even drastic warning: if you couldn’t patch, take your systems OFFLINE.&lt;/p&gt;

&lt;h2&gt;
  
  
  The story so far
&lt;/h2&gt;

&lt;p&gt;To see why, you need to understand the whole incident, and it starts long before AI.&lt;/p&gt;

&lt;p&gt;In 2004, security researcher Stefan Esser found the first remote flaw in how PHP handles its memory limit.&lt;/p&gt;

&lt;p&gt;In 2020, someone filed PHP bug #78876, noting that long form variables could make PHP run out of memory.&lt;/p&gt;

&lt;p&gt;It was treated as harmless.&lt;/p&gt;

&lt;p&gt;In 2024, an audit by OSTIF and Quarkslab rediscovered the same out-of-memory problem.&lt;/p&gt;

&lt;p&gt;No one could prove it was exploitable, so it stayed unfixed (Calif).&lt;/p&gt;

&lt;h3&gt;
  
  
  What the bugs actually are.
&lt;/h3&gt;

&lt;p&gt;PHP stops a request when it runs out of memory.&lt;/p&gt;

&lt;p&gt;If that happens halfway through building an internal data structure, PHP skips its cleanup.&lt;/p&gt;

&lt;p&gt;The memory is freed, but pointers to it survive.&lt;/p&gt;

&lt;p&gt;The next request handled by the same worker then trusts that freed memory, which an attacker has filled with their own data.&lt;/p&gt;

&lt;p&gt;Calif showed that one crafted upload, under PHP’s default 8 MiB upload limit, can exhaust its default 128 MiB memory limit.&lt;/p&gt;

&lt;p&gt;No login is needed, and no bug in the website’s own code.&lt;/p&gt;

&lt;p&gt;PHP filed the flaws as two CVEs: CVE-2026–109618 (out-of-memory corruption) and CVE-2026–109619 (stale state that survives into the next request).&lt;/p&gt;

&lt;p&gt;Both are rated 9.2 out of 10 (php.net).&lt;/p&gt;

&lt;h3&gt;
  
  
  The discovery.
&lt;/h3&gt;

&lt;p&gt;On 30 July 2026, OpenAI invited the security firm Calif into Patch the Planet, its program to help open-source maintainers.&lt;/p&gt;

&lt;p&gt;Calif’s Ryan Austin picked PHP.&lt;/p&gt;

&lt;p&gt;On 1 August, working with OpenAI’s GPT-5.6 Sol, he had a working remote code execution against WordPress.&lt;/p&gt;

&lt;p&gt;Calif reported the first bug to PHP on 11 August and sent a working exploit on 14 August.&lt;/p&gt;

&lt;p&gt;On 19 August, Wiz Research independently found the same family of bugs using Gemini 4 Argon, GPT-5.6 Sol and its own Wiz Atlas tool, and reported its variants on 24 August (Wiz).&lt;/p&gt;

&lt;h3&gt;
  
  
  The quiet window.
&lt;/h3&gt;

&lt;p&gt;For about 11 weeks, PHP’s maintainers built the fix while OpenAI coordinated a coalition.&lt;/p&gt;

&lt;p&gt;Linux distributions received patches early.&lt;/p&gt;

&lt;p&gt;Cloudflare, AWS, Google, Microsoft, Fastly, Akamai and others prepared firewall rules.&lt;/p&gt;

&lt;p&gt;OpenAI briefed the White House’s Super Intelligence Force, the Office of the National Cyber Director and CISA (OpenAI).&lt;/p&gt;

&lt;h3&gt;
  
  
  The break.
&lt;/h3&gt;

&lt;p&gt;The plan was to disclose on 22 October.&lt;/p&gt;

&lt;p&gt;On 20 October, an anonymous Hacker News post claimed the bugs were real.&lt;/p&gt;

&lt;p&gt;It was deleted, but screenshots spread to X and Mastodon, along with images and a short video of Calif’s private exploit tool, named PHP2Shell (Alexandre Daubois).&lt;/p&gt;

&lt;p&gt;PHP brought the release forward to 21 October at 14:00 UTC.&lt;/p&gt;

&lt;p&gt;watchTowr also confirmed the flaws were genuine.&lt;/p&gt;

&lt;p&gt;Cloudflare saw the first attacks at 07:43 UTC, more than six hours before any patch existed (Sansec).&lt;/p&gt;

&lt;h3&gt;
  
  
  The patch.
&lt;/h3&gt;

&lt;p&gt;PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 shipped on schedule.&lt;/p&gt;

&lt;p&gt;The NSA, the FBI, CISA, the UK’s National Cyber Security Centre and CERT-EU all issued alerts.&lt;/p&gt;

&lt;p&gt;In the Netherlands, DigiD, MijnOverheid, the House of Representatives’ site and the Dutch National Cyber Security Centre’s own site went offline (Patchstack, citing NOS).&lt;/p&gt;

&lt;p&gt;Cloudflare’s shares rose about 5% that day (Investing.com).&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding the bug is no longer the hard part
&lt;/h2&gt;

&lt;p&gt;Calif’s account is the clearest.&lt;/p&gt;

&lt;p&gt;Austin started from a theory, that ‘siblings’ of Esser’s 2004 bug still lurked in the code.&lt;/p&gt;

&lt;p&gt;He asked his model to look for ways to trigger a controllable out-of-memory error, then for code that could be interrupted mid-task.&lt;/p&gt;

&lt;p&gt;The model spotted that PHP counts a new table entry as live before it finishes building it.&lt;/p&gt;

&lt;p&gt;Austin then had it turn that one finding into a reusable search pattern, which led straight to more variants (Calif).&lt;/p&gt;

&lt;p&gt;Calif says it used no special harness and no models unavailable to the public.&lt;/p&gt;

&lt;p&gt;Its lesson is that knowing your target still matters. The expert supplied the direction. The model supplied the speed.&lt;/p&gt;

&lt;p&gt;Wiz tells the same story from the exploitation side.&lt;/p&gt;

&lt;p&gt;Building working attacks meant chaining several bugs and adapting to each target’s memory layout.&lt;/p&gt;

&lt;p&gt;With frontier models it adapted exploits across applications in hours, and a single researcher did in a week what Wiz says would once have taken a world-class team months (Wiz).&lt;/p&gt;

&lt;h3&gt;
  
  
  AI can find vulnerabilities faster than maintainers can fix them.
&lt;/h3&gt;

&lt;p&gt;If finding was the whole problem, PHP2Shell would have been fixed in 2020 or 2024.&lt;/p&gt;

&lt;p&gt;It wasn’t, and the PHP Foundation has said why.&lt;/p&gt;

&lt;p&gt;After the release, the Foundation explained that a possible exploit had been theorized as early as 2024.&lt;/p&gt;

&lt;p&gt;No concrete attack path was found, and other issues with clearer impact took priority.&lt;/p&gt;

&lt;p&gt;The experts who could fix it had many other responsibilities, so work on a fix stalled and restarted repeatedly over months (ABC News).&lt;/p&gt;

&lt;p&gt;OpenAI says these bugs are among several significant ones it has already found, and it expects such findings to “increase sharply” in the coming months.&lt;/p&gt;

&lt;h3&gt;
  
  
  A fix in PHP’s source code protects nobody until it runs on a server.
&lt;/h3&gt;

&lt;p&gt;That last step belongs to the people who operate websites, and PHP2Shell showed how unevenly it happens.&lt;/p&gt;

&lt;p&gt;After disclosure, Cloudflare says exploit attempts jumped from thousands to millions (Yahoo Finance).&lt;/p&gt;

&lt;p&gt;On 20 October, the security company Mallory counted about 884,000 internet-facing hosts reporting PHP 8.1 or older (The Hacker News).&lt;/p&gt;

&lt;p&gt;PHP no longer releases fixes for those versions.&lt;/p&gt;

&lt;p&gt;That is why the NSA’s advice included taking unpatchable systems offline, and why Japan’s Prime Minister suggested switching site features off (NSA).&lt;/p&gt;

&lt;p&gt;The Dutch government sites that went dark show that even well-resourced organizations reached for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The next PHP2Shell
&lt;/h2&gt;

&lt;p&gt;A Prime Minister asking a country to patch a programming language overnight sounds like a one-off but it probably isn’t.&lt;/p&gt;

&lt;p&gt;OpenAI expects findings like this to keep coming, and attackers already run AI campaigns for a few thousand dollars.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Web Components in Angular: The Good and Bad of Web Components</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Mon, 08 Sep 2025 07:26:47 +0000</pubDate>
      <link>https://dev.to/bytebantz/web-components-in-angular-the-good-and-bad-of-web-components-h64</link>
      <guid>https://dev.to/bytebantz/web-components-in-angular-the-good-and-bad-of-web-components-h64</guid>
      <description>&lt;p&gt;Normally, Angular components work &lt;strong&gt;only inside Angular applications&lt;/strong&gt;. But Angular &lt;strong&gt;createCustomElement()&lt;/strong&gt; allows you to turn an &lt;strong&gt;Angular component&lt;/strong&gt; into a &lt;strong&gt;custom HTML element&lt;/strong&gt; (also called a &lt;strong&gt;web component&lt;/strong&gt;) that can be used anywhere, even outside an Angular app while still keeping all of Angular’s features.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Web Components?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Web components&lt;/strong&gt; are a set of standards that allow developers to create custom HTML elements using JavaScript&lt;/p&gt;

&lt;p&gt;For example, in normal HTML, you have built-in elements like &amp;lt; button &amp;gt; or &amp;lt; input &amp;gt;. But what if you want a new type of element, like &amp;lt; cool-button &amp;gt;? You can create it using JavaScript.&lt;/p&gt;

&lt;p&gt;Web Components allow you to mix and match different UI components from various sources. However, just because you can doesn’t mean you should.&lt;/p&gt;

&lt;p&gt;If one Web Component uses React, another Vue, and another Angular, the browser has to load separate runtimes, which:&lt;/p&gt;

&lt;p&gt;❌Makes the page &lt;strong&gt;slower&lt;/strong&gt; (more JavaScript to download and execute).&lt;/p&gt;

&lt;p&gt;❌Increases &lt;strong&gt;file size&lt;/strong&gt; (bad for performance).&lt;/p&gt;

&lt;p&gt;❌Creates &lt;strong&gt;maintenance headaches&lt;/strong&gt; (hard to manage different technologies).&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages of using Web Components:
&lt;/h2&gt;

&lt;p&gt;✅&lt;strong&gt;Reusability:&lt;/strong&gt; Custom elements allow for code sharing across different projects.&lt;/p&gt;

&lt;p&gt;✅&lt;strong&gt;Flexibility:&lt;/strong&gt; They can be used in any web application regardless of the framework.&lt;/p&gt;

&lt;p&gt;✅&lt;strong&gt;Easy Integration:&lt;/strong&gt; They can be seamlessly added to existing web applications to introduce new functionality.&lt;/p&gt;

&lt;p&gt;✅&lt;strong&gt;Future-Proofing&lt;/strong&gt; — Based on web standards, reducing framework dependency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges involved in using Web Components:
&lt;/h2&gt;

&lt;p&gt;❌&lt;strong&gt;Browser Support&lt;/strong&gt;: Not all browsers support web components, which can limit usage in older browsers.&lt;/p&gt;

&lt;p&gt;❌&lt;strong&gt;Complexity:&lt;/strong&gt; Creating custom elements can be challenging.&lt;/p&gt;

&lt;p&gt;❌&lt;strong&gt;Debugging:&lt;/strong&gt; Debugging custom elements, especially in complex applications, can be difficult.&lt;/p&gt;

&lt;p&gt;Angular provides support for Web Components through &lt;strong&gt;Angular Elements&lt;/strong&gt;, allowing developers to create Web Components from Angular components.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;createCustomElement()&lt;/strong&gt; function takes an Angular component and turns it into a &lt;strong&gt;JavaScript class&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;const coolButtonElement = createCustomElement(CoolButtonComponent, { injector });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This JavaScript class can then be registered with the browser as a &lt;strong&gt;custom element&lt;/strong&gt; using the browser’s built-in &lt;strong&gt;customElements.define()&lt;/strong&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customElements.define('cool-button', coolButtonElement);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser keeps track of all custom elements using something called the &lt;strong&gt;CustomElementRegistry&lt;/strong&gt;, which links each tag (like &amp;lt; cool-button &amp;gt;) to its JavaScript class (CoolButton).&lt;/p&gt;

&lt;p&gt;⚠️ &lt;strong&gt;Important Note&lt;/strong&gt;&lt;br&gt;
Avoid using your Angular component’s selector as the Web Component tag name.&lt;/p&gt;

&lt;p&gt;For example, if your component’s selector is &lt;em&gt;app-alert&lt;/em&gt;, and you use it as the custom element tag &amp;lt; app-alert &amp;gt;&amp;lt; /app-alert &amp;gt;, it can cause issues.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;Angular might try to create two instances of the component for the same DOM element:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;One instance using the regular Angular component system.&lt;/li&gt;
&lt;li&gt;Another instance using the custom element registration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once you register this class with the browser’s &lt;strong&gt;custom element registry&lt;/strong&gt;, it becomes a special HTML tag that you can use just like any built-in HTML element (e.g., &amp;lt; cool-button &amp;gt;&amp;lt; /cool-button &amp;gt;).&lt;/p&gt;
&lt;h2&gt;
  
  
  Handling Inputs &amp;amp; Outputs in Web Components
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Handling Inputs&lt;/strong&gt;&lt;br&gt;
When you convert an Angular component into a custom element, the process automatically handles the &lt;strong&gt;input properties&lt;/strong&gt; and &lt;strong&gt;converts them into attributes&lt;/strong&gt; for the custom element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom elements&lt;/strong&gt; require &lt;strong&gt;attributes&lt;/strong&gt; to use &lt;strong&gt;dash-separated lowercase names&lt;/strong&gt;, and they don’t recognize &lt;strong&gt;camelCase&lt;/strong&gt; which Angular uses for property names.&lt;/p&gt;

&lt;p&gt;Angular automatically changes the input property names from &lt;strong&gt;camelCase&lt;/strong&gt; (like myInputProp) to &lt;strong&gt;dash-separated lowercase&lt;/strong&gt; (like my-input-prop) so that it fits the &lt;strong&gt;custom element&lt;/strong&gt; requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handling Outputs&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Angular automatically converts output events to Custom Events&lt;/strong&gt; and uses either the original output name or the alias you provide as the event name for the custom element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1: No alias&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have a component with this output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Output() valueChanged = new EventEmitter();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the event valueChanged is triggered, it becomes a Custom Event in the DOM, and you can listen to it like this in HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;my-element (valueChanged)="handleValueChanged($event)"&amp;gt;&amp;lt;/my-element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 2: With alias&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you use an alias with the &lt;strong&gt;@Output()&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;@Output('myClick') clicks = new EventEmitter();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, the custom event name becomes myClick instead of clicks. You can listen to it 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;&amp;lt;my-element (myClick)="handleClick($event)"&amp;gt;&amp;lt;/my-element&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Shadow DOM and Encapsulation
&lt;/h2&gt;

&lt;p&gt;Web Components are rendered in the shadow DOM&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Terms&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shadow Host&lt;/strong&gt; 🏠: The regular DOM element to which a shadow DOM is attached&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shadow Tree&lt;/strong&gt; 🌳: The DOM structure inside the shadow DOM. This tree is encapsulated, meaning styles and scripts from the main document won’t affect it unless explicitly allowed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shadow Boundary&lt;/strong&gt; ✋: The invisible boundary separating the shadow DOM from the main DOM. Anything outside this boundary can’t directly style or interact with shadow DOM elements&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shadow Root&lt;/strong&gt; 🌱: The root of the shadow tree. It’s where all shadow content starts.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Shadow DOM&lt;/strong&gt; is a way to encapsulate styles and behavior within a web component. This means that elements inside a &lt;strong&gt;Shadow DOM&lt;/strong&gt; behave as if they are in a separate, isolated world. The styles outside don’t affect them, and their styles don’t affect the rest of the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is this useful?
&lt;/h2&gt;

&lt;p&gt;✅It prevents conflicts between styles and scripts from different parts of a website.&lt;/p&gt;

&lt;p&gt;✅It allows developers to create &lt;strong&gt;reusable components&lt;/strong&gt; without worrying about breaking the rest of the page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But This Encapsulation Also Brings Challenges!&lt;/strong&gt;&lt;br&gt;
Because the Shadow DOM is isolated, certain &lt;strong&gt;normal browser behaviors don’t work as expected&lt;/strong&gt;. Some events don’t bubble out of the Shadow DOM, certain form elements don’t behave normally, and even CSS has limitations.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Are the Key Challenges?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Events Might Not Bubble&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Normally, when you click an element, the event “bubbles up” to parent elements.&lt;br&gt;
But inside the Shadow DOM, some events (like focusin) stop at the Shadow boundary and don’t continue to the outer document.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Some Events Behave Differently&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Events like focusin and mouseenter don’t behave as expected because the Shadow DOM treats the entire component as a single unit.&lt;br&gt;
A child element inside the Shadow DOM might gain focus, but the event reports that the focus is on the whole component instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. CSS Encapsulation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Styles inside a Shadow DOM don’t affect elements outside it, and vice versa.&lt;br&gt;
This is great for preventing unwanted style conflicts but can cause issues if you need to apply global styles to Shadow DOM elements.&lt;/p&gt;
&lt;h2&gt;
  
  
  Web Components and SSR
&lt;/h2&gt;

&lt;p&gt;Web Components rely on browser APIs like &lt;strong&gt;customElements.define(), shadow DOM&lt;/strong&gt;, and &lt;strong&gt;HTML templates&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;These APIs don’t exist on the server, which means &lt;strong&gt;Web Components&lt;/strong&gt; don’t naturally work in a &lt;strong&gt;server-side rendering (SSR)&lt;/strong&gt; environment.&lt;/p&gt;

&lt;p&gt;Developers need to create extra wrappers or tricks to make &lt;strong&gt;Web Components&lt;/strong&gt; generate server-side HTML before &lt;strong&gt;hydration&lt;/strong&gt; (the process of making server-rendered HTML interactive).&lt;/p&gt;

&lt;p&gt;This adds &lt;strong&gt;complexity&lt;/strong&gt; and &lt;strong&gt;performance overhead&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Shadow DOM and Hydration Issues
&lt;/h2&gt;

&lt;p&gt;Since Web Components rely on Shadow DOM, they don’t naturally fit into modern hydration strategies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For example, Incremental hydration depends on event delegation,&lt;/strong&gt; meaning Angular places global event listeners on the  or a parent component to capture interactions &lt;strong&gt;before hydrating a component.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;However, &lt;strong&gt;Shadow DOM blocks event delegation&lt;/strong&gt; because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Events do not bubble past the shadow root.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Global event listeners in Angular cannot detect interactions inside a Web Component using Shadow DOM.&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What this means:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If a Web Component inside an SSR-rendered Angular app is not hydrated, clicks inside it won’t trigger Angular’s hydration logic.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Angular will &lt;strong&gt;never detect interactions inside a Shadow DOM&lt;/strong&gt; unless explicitly re-dispatched.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Web Components and Angular Routing
&lt;/h2&gt;

&lt;p&gt;When trying to host a second Angular app as a Web Component within another Angular application, routing often doesn’t work for the hosted app because each Angular application typically has its own isolated router instance; essentially, the parent application’s router doesn’t recognize routes defined within the child web component&lt;/p&gt;
&lt;h2&gt;
  
  
  Web Components Use Cases
&lt;/h2&gt;

&lt;p&gt;1️⃣ &lt;strong&gt;Simplifying Dynamic Component Loading&lt;/strong&gt;&lt;br&gt;
Previously, if you wanted to add a component to a page dynamically (meaning you load it at runtime, not when the page is initially loaded), you had to do things like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the component.&lt;/li&gt;
&lt;li&gt;Add it to the DOM manually (the HTML structure).&lt;/li&gt;
&lt;li&gt;Manually set up dependency injection (services, data) and change detection (keep the view updated).&lt;/li&gt;
&lt;li&gt;Manually wire up events (like clicking buttons, etc.).
This required a lot of code and was pretty complex.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;With Custom Elements:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using &lt;strong&gt;Angular Custom Elements&lt;/strong&gt; makes this process much simpler. Here’s how:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create the Angular component as usual (with your template and logic).&lt;/li&gt;
&lt;li&gt;Convert it to a custom element using Angular’s built-in tools.&lt;/li&gt;
&lt;li&gt;Use it in your HTML as if it were a regular HTML element (like &amp;lt; app-dynamic-component &amp;gt;&amp;lt; /app-dynamic-component &amp;gt;), and Angular takes care of all the setup, dependency injection, and event handling for you.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This results in a simplified and streamlined process for dynamically loading components, reducing the amount of code you need to write and making your app easier to maintain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Step 1: Create a New Angular Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new web-components-demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Install the @angular/elements package:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @angular/elements --save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Create a Dynamic Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng generate component dynamic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit the dynamic.component.ts file to include some basic logic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component, input } from '@angular/core';

@Component({
  selector: 'app-dynamic',
  imports: [],
  template: `&amp;lt;div&amp;gt;{{ text() }}&amp;lt;/div&amp;gt;`,
})
export class DynamicComponent {
  text = input&amp;lt;string&amp;gt;('Default dynamic message!');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4: Register the Web Component&lt;/p&gt;

&lt;p&gt;In your main.ts, register the DynamicComponent as a web component using Angular Elements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';
import { createCustomElement } from '@angular/elements';
import { DynamicComponent } from './app/dynamic/dynamic.component';

// Bootstrap the application
bootstrapApplication(AppComponent, appConfig)
  .then((app) =&amp;gt; {
    const dynamicElement = createCustomElement(DynamicComponent, {
      injector: app.injector
    });
    customElements.define('dynamic-component', dynamicElement); // Register the web component
  })
  .catch((err) =&amp;gt; console.error(err));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5: Dynamically Load the Web Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In your &lt;strong&gt;app.component.ts&lt;/strong&gt;, create and insert the web component directly into the DOM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    &amp;lt;button (click)="createComponent()"&amp;gt;Create Dynamic Component&amp;lt;/button&amp;gt;
    &amp;lt;button (click)="destroyComponent()"&amp;gt;Destroy Dynamic Component&amp;lt;/button&amp;gt;
    &amp;lt;div id="container"&amp;gt;&amp;lt;/div&amp;gt;
  `,
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  createComponent() {
    const dynamicComponent = document.createElement('dynamic-component'); // Use the registered tag name
    dynamicComponent.setAttribute(
      'text',
      'Hello, this is a dynamic web component!'
    );
    document.querySelector('#container')?.appendChild(dynamicComponent);
  }

  destroyComponent() {
    const container = document.querySelector('#container');
    if (container) {
      container.innerHTML = ''; // Clear the container to remove all dynamic components
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Shared Design System&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Web Components are great &lt;strong&gt;when you need reusable UI elements that work across different frameworks or projects&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine you’re building a &lt;strong&gt;large-scale application&lt;/strong&gt; that has multiple teams working on different sections of the UI. One team uses &lt;strong&gt;Angular&lt;/strong&gt;, another uses &lt;strong&gt;React&lt;/strong&gt;, and a third one uses &lt;strong&gt;Vue&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of each team recreating buttons, modals, and form elements &lt;strong&gt;in their own framework&lt;/strong&gt;, you can build &lt;strong&gt;a set of Web Components&lt;/strong&gt; that work everywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  How This Helps
&lt;/h2&gt;

&lt;p&gt;✅ &lt;strong&gt;Framework-Agnostic:&lt;/strong&gt; A Web Component like  can be used in React, Vue, Angular, or even plain HTML.&lt;br&gt;
✅ &lt;strong&gt;Single Source of Truth:&lt;/strong&gt; Instead of maintaining separate versions of the same button in different frameworks, you maintain one component.&lt;br&gt;
✅ &lt;strong&gt;Consistent UI:&lt;/strong&gt; The design stays the same no matter where it’s used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Step 1: Create a new Angular project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new shared-design-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Generate a new Angular element (Web Component)&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;ng generate component my-button
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Modify my-button.component.ts&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;import { Component, input } from '@angular/core';

@Component({
  selector: 'app-my-button',
  imports: [],
  template: `&amp;lt;button class="my-button"&amp;gt;{{ label() }}&amp;lt;/button&amp;gt;`,
  styles: [
    `.my-button {
      background-color: #007bff;
      color: white;
      padding: 10px 20px;
      border: none;
      border-radius: 5px;
      cursor: pointer;
      font-size: 16px;
    }`
  ]
})
export class MyButtonComponent {
  label = input&amp;lt;string&amp;gt;('Click Me');
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Convert it into a Web Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modify main.ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { createCustomElement } from '@angular/elements';
import { MyButtonComponent } from './app/my-button/my-button.component';


// Bootstrap the application
createApplication(appConfig)
  .then((app) =&amp;gt; {
    const myButtonElement = createCustomElement(MyButtonComponent, {
      injector: app.injector
    });
    customElements.define('my-button', myButtonElement); // Register the web component
  })
  .catch((err) =&amp;gt; console.error(err));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The key reason createApplication is better for pure Web Components is that it does not automatically render a root component in Angular, unlike bootstrapApplication. Instead, it only initializes the Angular injector and allows you to register custom elements manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Build the Angular Web Component&lt;/strong&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng build --output-hashing=none
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 6: Test the Web Component&lt;/p&gt;

&lt;p&gt;To support older browsers, polyfills may be needed to provide support for web components.&lt;/p&gt;

&lt;p&gt;If you import polyfills in main.ts, they become part of your main JavaScript bundle. This is fine if you’re only using one Angular web component.&lt;/p&gt;

&lt;p&gt;If you embed multiple custom elements (Angular web components) on a page, each one might load the same polyfills multiple times. This can slow down your app or cause errors.&lt;/p&gt;

&lt;p&gt;Instead of importing polyfills inside main.ts, you can load them separately using a &amp;lt; script &amp;gt; tag in your HTML. This way, they are loaded only once for all components.&lt;/p&gt;

&lt;p&gt;Create a simple index.html:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8" /&amp;gt;
    &amp;lt;title&amp;gt;Web Component Demo&amp;lt;/title&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1" /&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;my-button&amp;gt;&amp;lt;/my-button&amp;gt;

    &amp;lt;script src="polyfills.js" type="module"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;script src="main.js" type="module"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to make your custom elements type-safe
&lt;/h2&gt;

&lt;p&gt;In standard DOM methods like &lt;strong&gt;document.createElement()&lt;/strong&gt; or &lt;strong&gt;document.querySelector()&lt;/strong&gt;, TypeScript infers the type of the element returned based on the argument you provide.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;document.createElement(‘a’)&lt;/strong&gt; returns an HTMLAnchorElement with specific properties like href.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;document.createElement(‘div’)&lt;/strong&gt; returns an HTMLDivElement, which doesn’t have an href property.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, when using &lt;strong&gt;custom elements&lt;/strong&gt;, TypeScript can’t automatically infer the type because it doesn’t know the specific properties of that element.&lt;/p&gt;

&lt;p&gt;It just thinks it’s a basic &lt;strong&gt;HTMLElement&lt;/strong&gt; (a generic HTML element). For example, it doesn’t know your my-dialog element has a content property.&lt;/p&gt;

&lt;p&gt;You have two ways to get TypeScript to understand the properties of your custom elements:&lt;br&gt;
&lt;strong&gt;1. Casting the Type Manually&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you create the custom element, you can &lt;strong&gt;cast&lt;/strong&gt; it to a more specific type that knows about the properties it has.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const dialog = document.createElement('my-dialog') as NgElement &amp;amp; WithProperties&amp;lt;{ content: string }&amp;gt;;
dialog.content = 'Hello, world!';  // Now TypeScript knows 'content' is a string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This way, TypeScript will now know that &lt;strong&gt;dialog.content&lt;/strong&gt; should be a string and give you features like &lt;strong&gt;type checking&lt;/strong&gt; and &lt;strong&gt;autocomplete&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;You have to write this casting (as &lt;strong&gt;NgElement &amp;amp; WithProperties) every time&lt;/strong&gt; you create a custom element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Augmenting TypeScript’s Default Knowledge of Elements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of casting every time, you can tell TypeScript about your custom elements once by adding a special definition.&lt;/p&gt;

&lt;p&gt;This is done by extending the &lt;strong&gt;HTMLElementTagNameMap&lt;/strong&gt; which is how TypeScript knows what properties different HTML tags should have.&lt;/p&gt;

&lt;p&gt;For example, you can add this globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;declare global {
  interface HTMLElementTagNameMap {
    'my-dialog': NgElement &amp;amp; WithProperties&amp;lt;{ content: string }&amp;gt;;
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, you don’t need to cast the element manually every time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const dialog = document.createElement('my-dialog');
dialog.content = 'Hello, world!';  // TypeScript knows 'content' is a string automatically
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using &lt;strong&gt;augmentation&lt;/strong&gt; is simpler and avoids repetitive code. It ensures TypeScript automatically knows the properties of your custom elements, making your code cleaner.&lt;/p&gt;

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

&lt;p&gt;Web Components provide a powerful way to create reusable UI elements that can work across different frameworks. By using Angular Elements, you can easily create and manage these components while maintaining the benefits of Angular’s architecture.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Say Goodbye to EventEmitter: Switch to output() for Custom Events in Angular</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Wed, 03 Sep 2025 09:52:41 +0000</pubDate>
      <link>https://dev.to/bytebantz/say-goodbye-to-eventemitter-switch-to-output-for-custom-events-in-angular-17h</link>
      <guid>https://dev.to/bytebantz/say-goodbye-to-eventemitter-switch-to-output-for-custom-events-in-angular-17h</guid>
      <description>&lt;p&gt;In Angular, components can communicate with each other by &lt;strong&gt;raising events&lt;/strong&gt;. For example, when a user clicks a button inside a component, you might want to notify its parent component about that action.&lt;/p&gt;

&lt;p&gt;To do that, Angular allows us to define &lt;strong&gt;custom events&lt;/strong&gt; using the &lt;strong&gt;@Output decorator and EventEmitter&lt;/strong&gt; (old way) or the &lt;strong&gt;output()&lt;/strong&gt; function (new way).&lt;/p&gt;

&lt;p&gt;This enables you to create events that can be emitted and handled by parent components, similar to native DOM events.&lt;/p&gt;

&lt;h2&gt;
  
  
  Old Way: Using @Output and EventEmitter
&lt;/h2&gt;

&lt;p&gt;The traditional approach is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You define an event using the &lt;strong&gt;@Output decorator&lt;/strong&gt; and an &lt;strong&gt;instance of EventEmitter&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You emit the event using &lt;strong&gt;.emit()&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  New Way: Using the output Function
&lt;/h2&gt;

&lt;p&gt;Now, Angular introduces a &lt;strong&gt;simplified syntax&lt;/strong&gt; to define custom events without needing &lt;strong&gt;EventEmitter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of using &lt;strong&gt;@Output() and EventEmitter&lt;/strong&gt;, you can use the &lt;strong&gt;output()&lt;/strong&gt; function directly.&lt;/p&gt;

&lt;p&gt;The newer approach &lt;strong&gt;eliminates&lt;/strong&gt; the need to explicitly instantiate an &lt;strong&gt;EventEmitter&lt;/strong&gt;, which simplifies code and reduces boilerplate.&lt;/p&gt;

&lt;p&gt;Even though the syntax is different, &lt;strong&gt;the behavior is exactly the same&lt;/strong&gt; as the old approach. You still emit events, pass data with them, and listen for them from the parent component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Basic Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To create a custom event, you define a property in your component using the &lt;strong&gt;output function&lt;/strong&gt;, which returns an &lt;strong&gt;OutputEmitterRef&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;import { Component, output } from '@angular/core';

@Component({
  selector: 'child-component',
  template: `&amp;lt;button (click)="sendData()"&amp;gt;Click Me&amp;lt;/button&amp;gt;`,
})
export class ChildComponent {
  dataSent = output&amp;lt;string&amp;gt;(); // No need to import EventEmitter

  sendData() {
    this.dataSent.emit('Hello, Parent!');
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, the &lt;strong&gt;output function&lt;/strong&gt; does exactly what &lt;strong&gt;EventEmitter&lt;/strong&gt; did, but in a more compact form.&lt;/p&gt;

&lt;p&gt;Whether you’re using the old or new way, the way you listen for the event in the parent component is the same.&lt;/p&gt;

&lt;p&gt;In the parent component, you can listen for the &lt;strong&gt;dataSent&lt;/strong&gt; event using the regular event binding syntax &lt;strong&gt;(eventName)&lt;/strong&gt; and call a method when the event is triggered.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';

@Component({
  selector: 'app-parent',
  template: `
    &amp;lt;h1&amp;gt;Parent Component&amp;lt;/h1&amp;gt;
    &amp;lt;child-component (dataSent)="receiveData($event)"&amp;gt;&amp;lt;/child-component&amp;gt;
    &amp;lt;p&amp;gt;{{ receivedMessage }}&amp;lt;/p&amp;gt;
  `,
})
export class ParentComponent {
  receivedMessage: string = '';

  // Method to handle the received data from the child component
  receiveData(message: string) {
    this.receivedMessage = message; // Store the message received from the child
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Customizing Output Names
&lt;/h2&gt;

&lt;p&gt;You can specify a custom name for the event in the template using the alias option&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;changed = output({alias: 'valueChanged'});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;· The alias option only affects how the event is referenced in the template, not in TypeScript code.&lt;/p&gt;

&lt;p&gt;· In the TypeScript code, the original name of the output property is used (in this case, changed).&lt;/p&gt;

&lt;p&gt;· In the template, the alias name valueChanged is used to listen for the event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subscribing to Outputs Programmatically
&lt;/h2&gt;

&lt;p&gt;When dynamically creating components in Angular, you might want to listen for events emitted by the component, for example, when a button inside the dynamically created component is clicked.&lt;/p&gt;

&lt;p&gt;You can do this by subscribing to their output events programmatically using &lt;strong&gt;subscribe&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;After creating the dynamic component in the parent component, we can subscribe to its event property to listen for it.&lt;/p&gt;

&lt;p&gt;When the event is emitted, the subscription in the parent component’s code will receive the emitted data and can take an action based on it, such as logging it to the console, updating the UI, or performing some other logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const componentRef = viewContainerRef.createComponent(SomeComponent);

// Subscribe to the dynamically created component's output event
componentRef.instance.someEventProperty.subscribe((eventData) =&amp;gt; {
  console.log(eventData); 
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also unsubscribe manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const eventSubscription = componentRef.instance.someEventProperty.subscribe(eventData =&amp;gt; {
  console.log(eventData);
});

eventSubscription.unsubscribe();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Points about Custom Events
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom events do not bubble:&lt;/strong&gt; In native DOM events, when an event is triggered, it can propagate up from the target element to its ancestors, allowing parent elements to listen for events on child elements. However, custom events in Angular do not bubble.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Case sensitivity:&lt;/strong&gt; Output names are case-sensitive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inheritance:&lt;/strong&gt; When a component extends another, it inherits the outputs from the parent component. This means child component automatically inherits the output (custom event) from the parent and can listen to or trigger it without needing to redefine the event.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Event names:&lt;/strong&gt; Choose event names carefully to avoid conflicts with native DOM event names like click, focus, etc.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In conclusion, Angular provides two approaches for component communication through custom events: the traditional method using &lt;strong&gt;@Output() and EventEmitter&lt;/strong&gt;, and the newer, simpler &lt;strong&gt;output() function&lt;/strong&gt;. The newer approach &lt;strong&gt;eliminates the need for importing EventEmitter&lt;/strong&gt; and &lt;strong&gt;reduces boilerplate code, making the code more concise and easier to maintain.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Why you should use @use instead of @import in Angular Projects</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Tue, 02 Sep 2025 13:57:37 +0000</pubDate>
      <link>https://dev.to/bytebantz/why-you-should-use-use-instead-of-import-in-angular-projects-56kf</link>
      <guid>https://dev.to/bytebantz/why-you-should-use-use-instead-of-import-in-angular-projects-56kf</guid>
      <description>&lt;p&gt;Before the introduction of &lt;a class="mentioned-user" href="https://dev.to/use"&gt;@use&lt;/a&gt;, developers used &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/import"&gt;@import&lt;/a&gt;&lt;/strong&gt; to bring styles from different files into one. However, &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/import"&gt;@import&lt;/a&gt;&lt;/strong&gt; had some issues:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It could &lt;strong&gt;import the same file multiple times&lt;/strong&gt;, leading to &lt;strong&gt;bloated&lt;/strong&gt; CSS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It &lt;strong&gt;pulled in everything&lt;/strong&gt; from the imported file, &lt;strong&gt;even unused styles&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It caused naming conflicts when multiple files had variables with the same name.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To fix these, Sass introduced &lt;a class="mentioned-user" href="https://dev.to/use"&gt;@use&lt;/a&gt;, which:&lt;/p&gt;

&lt;p&gt;✔ &lt;strong&gt;Loads each file only once&lt;/strong&gt;.&lt;br&gt;
✔ &lt;strong&gt;Uses namespaces to avoid variable conflicts&lt;/strong&gt;.&lt;br&gt;
✔ Helps make CSS more optimized by &lt;strong&gt;importing only what’s needed&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: @ import (Old way)&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;// colors.scss
$primary-color: blue;
$secondary-color: red;


// styles.scss
@import 'colors';

body {
  background-color: $primary-color;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; If &lt;strong&gt;colors.scss&lt;/strong&gt; is &lt;strong&gt;imported multiple times&lt;/strong&gt; across different files, it could cause &lt;strong&gt;duplication&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: @ use (New way)&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;// colors.scss
$primary-color: blue;
$secondary-color: red;

// styles.scss
@use 'colors';

body {
  background-color: colors.$primary-color;  // Notice the namespace "colors."
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why is this better?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/use"&gt;@use&lt;/a&gt;&lt;/strong&gt; statement &lt;strong&gt;ensures colors.scss is only loaded once&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Variables need to be prefixed&lt;/strong&gt; with the file name (colors.$primary-color), &lt;strong&gt;preventing conflicts&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Using &lt;a class="mentioned-user" href="https://dev.to/use"&gt;@use&lt;/a&gt; with an Alias&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of typing &lt;strong&gt;colors.$primary-color&lt;/strong&gt; every time, we can &lt;strong&gt;shorten&lt;/strong&gt; it using as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@use 'colors' as c;

body {
  background-color: c.$primary-color;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Benefit:&lt;/strong&gt; Shorter and more readable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a class="mentioned-user" href="https://dev.to/use"&gt;@use&lt;/a&gt; in Angular Material&lt;/strong&gt;&lt;br&gt;
Angular Material switched to @ use for theming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Old way (&lt;a class="mentioned-user" href="https://dev.to/import"&gt;@import&lt;/a&gt;):&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;@import '@angular/material';
$my-primary: mat-palette($mat-indigo);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;New way (&lt;a class="mentioned-user" href="https://dev.to/use"&gt;@use&lt;/a&gt;):&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;@use '@angular/material' as mat;
$my-primary: mat.define-palette(mat.$indigo-palette, 500);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Understanding @forward rule in Sass
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;@ forward&lt;/strong&gt; rule in Sass works together with &lt;strong&gt;@ use&lt;/strong&gt; to organize and control access to styles.&lt;/p&gt;

&lt;p&gt;It allows you to re-export styles from one file to another while keeping some variables, mixins, or functions private.&lt;/p&gt;

&lt;p&gt;Before Sass introduced &lt;strong&gt;@ forward&lt;/strong&gt;, using &lt;strong&gt;@ import&lt;/strong&gt; meant that everything in a file was always accessible, leading to bloated styles and naming conflicts.&lt;/p&gt;

&lt;p&gt;If you want to explicitly control which variables get exposed, you can use &lt;strong&gt;@forward&lt;/strong&gt; with the show keyword.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Forwarding Only Some Variables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you only want to expose specific variables, use show:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;_colors.scss&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;$primary-color: blue;
$secondary-color: red;
$private-color: black; // ❌ Should not be public

@forward 'colors' show $primary-color, $secondary-color;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;main.scss&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;@use 'colors';

body {
  background-color: colors.$primary-color; // ✅ Works
  color: colors.$secondary-color;          // ✅ Works
  border: 1px solid colors.$private-color; // ❌ ERROR! Not exposed
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you use &lt;strong&gt;@ forward&lt;/strong&gt; without &lt;strong&gt;show&lt;/strong&gt;, then all public variables, mixins, and functions from that module are &lt;strong&gt;automatically forwarded&lt;/strong&gt; and accessible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Forwarding Everything&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;_colors.scss&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;$primary-color: blue;
$secondary-color: red;
$private-color: black; // This is still public unless restricted

@forward 'colors'; // ✅ Everything is forwarded
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;main.scss&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;@use 'colors';

body {
  background-color: colors.$primary-color; // ✅ Works
  color: colors.$secondary-color;          // ✅ Works
  border: 1px solid colors.$private-color; // ✅ Also works
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since &lt;strong&gt;@forward&lt;/strong&gt; is used without show, public variables, mixins, and functions from _colors.scss are available in main.scss&lt;/p&gt;

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

&lt;p&gt;In short, &lt;strong&gt;@ use&lt;/strong&gt; provides better performance, prevents conflicts, and ensures cleaner, more efficient stylesheets, making it the preferred choice for modern Sass development.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Angular Best Practices Every Developer Needs to Know</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Tue, 02 Sep 2025 11:29:20 +0000</pubDate>
      <link>https://dev.to/bytebantz/angular-best-practices-every-developer-needs-to-know-39k0</link>
      <guid>https://dev.to/bytebantz/angular-best-practices-every-developer-needs-to-know-39k0</guid>
      <description>&lt;p&gt;Writing clean, maintainable, and performant Angular applications requires following best practices that enhance readability, testability, and performance.&lt;/p&gt;

&lt;p&gt;Here are 6 key principles every Angular developer should follow:&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Avoiding logic in Angular templates
&lt;/h1&gt;

&lt;p&gt;Avoiding logic in Angular templates helps maintain cleaner, more maintainable code. Here’s why and how you should do it:&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Avoid Logic in Templates?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Performance Optimization&lt;/strong&gt; — Function calls in templates are executed repeatedly during change detection, which can impact performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Better Testability&lt;/strong&gt; — Moving logic to the component makes it easier to write unit tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Improved Maintainability&lt;/strong&gt; — Keeping business logic separate from the template reduces the risk of breaking functionality when modifying the UI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Enhanced Readability&lt;/strong&gt; — Templates remain clean and focused on presentation rather than logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Extract Logic from Templates
&lt;/h2&gt;

&lt;p&gt;Instead of doing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div *ngIf="isUserLoggedIn()"&amp;gt;{{ getUserName() }}&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Move the logic to the component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class ExampleComponent {
  isLoggedIn = false;
  userName = '';

  constructor(private authService: AuthService) {
    this.isLoggedIn = this.authService.isAuthenticated();
    this.userName = this.authService.getUserName();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use it in the template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div *ngIf="isLoggedIn"&amp;gt;{{ userName }}&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures the function isn’t re-evaluated unnecessarily and improves performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Using Aliases for Cleaner Imports
&lt;/h2&gt;

&lt;p&gt;In a deep folder structure, import paths can become long and messy.&lt;/p&gt;

&lt;p&gt;Using &lt;strong&gt;aliases&lt;/strong&gt; can help keep your import paths clean and manageable in such projects with deep folder structures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of bad imports:&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;import { MyComponent } from '../../../components/MyComponent';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This import path is &lt;strong&gt;long, hard to understand&lt;/strong&gt;, and &lt;strong&gt;can easily break&lt;/strong&gt; when files are moved around.&lt;/p&gt;

&lt;p&gt;Instead, &lt;strong&gt;aliases&lt;/strong&gt; allow you to define a short path to access files and components, &lt;strong&gt;improving clarity&lt;/strong&gt; and &lt;strong&gt;reducing the chances of errors&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In Angular projects, &lt;strong&gt;aliases&lt;/strong&gt; are set up in the &lt;strong&gt;tsconfig.json&lt;/strong&gt; file.&lt;/p&gt;

&lt;p&gt;Here’s an example:&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;tsconfig.json&lt;/strong&gt; file, we will use the &lt;strong&gt;paths property&lt;/strong&gt; to define &lt;strong&gt;aliases&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;"compilerOptions": {
  "baseUrl": "./",
  "paths": {
    "@app/*": ["src/app/*"],
    "@services/*": ["src/app/services/*"],
    "@components/*": ["src/app/components/*"]
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you’ve set up your &lt;strong&gt;aliases&lt;/strong&gt;, you can use them in your &lt;strong&gt;imports&lt;/strong&gt;.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { MyComponent } from '@components/MyComponent';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of writing a long import path like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { MyComponent } from '../../../components/MyComponent';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How Aliases Improve Your Workflow:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Improved Readability:&lt;/strong&gt; Aliases make it clear where your files are located. For instance, @components or &lt;a class="mentioned-user" href="https://dev.to/services"&gt;@services&lt;/a&gt; give a clear context of what’s being imported, making your codebase easier to navigate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Refactoring Made Easy:&lt;/strong&gt; You can move files, folders, or entire sections of your application without worrying about breaking import paths throughout your project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consistency:&lt;/strong&gt; With aliases, your import paths are consistent across the entire project, reducing the chance of errors.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Avoid Nested Subscriptions in RxJS
&lt;/h2&gt;

&lt;p&gt;When handling multiple streams of data (like user input, API requests, or events), a common mistake is subscribing inside another subscription.&lt;/p&gt;

&lt;p&gt;This leads to the following main problems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Multiple ongoing requests →&lt;/strong&gt; If a new request starts before the previous one finishes, multiple requests run at the same time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Race conditions →&lt;/strong&gt; The responses don’t always come back in order, so old data can overwrite new data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory leaks →&lt;/strong&gt; Unnecessary active subscriptions can slow down the app and use extra memory.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Instead, we should use &lt;strong&gt;switchMap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;switchMap&lt;/strong&gt; makes sure that only &lt;strong&gt;the latest request is completed&lt;/strong&gt; and &lt;strong&gt;all previous requests are canceled&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How This Looks in Code (Nested Subscriptions)&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;pickupLocation$.subscribe(location =&amp;gt; {
  findDriver$(location).subscribe(driver =&amp;gt; {
    console.log(`Driver assigned: ${driver}`);
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If you update your location multiple times, multiple driver searches run at the same time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The first request may return after the second, assigning the wrong driver.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Using switchMap (Cancels Old Requests)&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;pickupLocation$.pipe(
  switchMap(location =&amp;gt; findDriver$(location)) // Cancels old requests
).subscribe(driver =&amp;gt; {
  console.log(`Driver assigned: ${driver}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fixed Problems:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Only one active search at a time&lt;/strong&gt; (old requests are canceled).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Always get the correct driver for your latest request&lt;/strong&gt; (no outdated responses).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using switchMap ensures only the latest request matters, preventing outdated responses, unnecessary operations&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Breaking large components into smaller, reusable component
&lt;/h2&gt;

&lt;p&gt;As an Angular application grows, components tend to become large and difficult to maintain.&lt;/p&gt;

&lt;p&gt;A single component that handles multiple responsibilities is harder to debug, test, and manage.&lt;/p&gt;

&lt;p&gt;So, the idea is to &lt;strong&gt;split the large component into smaller ones&lt;/strong&gt; that follows the &lt;strong&gt;Single Responsibility Principle (SRP)&lt;/strong&gt;, meaning each handle a specific task.&lt;/p&gt;

&lt;p&gt;This way, you can test, debug, and reuse each smaller component more easily.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Transforming a Large Component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s say we have a large Angular component that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Displays a list of items.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Filters items based on a search input.&lt;br&gt;
&lt;strong&gt;Before Splitting: The Large Component&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!-- main.component.html --&amp;gt;
&amp;lt;div&amp;gt;
  &amp;lt;input [(ngModel)]="searchTerm" placeholder="Search..." /&amp;gt;
  &amp;lt;div *ngFor="let item of filterItems(items, searchTerm)"&amp;gt;
    &amp;lt;h3&amp;gt;{{ item.title }}&amp;lt;/h3&amp;gt;
    &amp;lt;p&amp;gt;{{ item.description }}&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// main.component.ts
export class MainComponent {
  items = [
    { title: 'fist item', description: 'Description of Item 1' },
    { title: 'second item', description: 'Description of Item 2' },
    { title: 'third item', description: 'Description of Item 3' }
  ];
  searchTerm = '';

  filterItems(items: any[], term: string) {
    return items.filter((item) =&amp;gt; item.title.includes(term));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;After Splitting: Smaller Components&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To make the component more reusable, we break it down into:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Search Bar Component&lt;/strong&gt; — Handles search input.&lt;br&gt;
&lt;strong&gt;2. Item List Component&lt;/strong&gt; — Displays a list of items.&lt;br&gt;
&lt;strong&gt;3. Item Component&lt;/strong&gt; — Displays a single item.&lt;br&gt;
&lt;strong&gt;4. Search Bar Component (search-bar.component.ts)&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;&amp;lt;!-- search-bar.component.html --&amp;gt;
&amp;lt;input [(ngModel)]="searchTerm" (input)="search.emit(searchTerm)" placeholder="Search..." /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// search-bar.component.ts
import { Component, EventEmitter, Output } from '@angular/core';

@Component({
  selector: 'app-search-bar',
  templateUrl: './search-bar.component.html',
})
export class SearchBarComponent {
  @Output() search = new EventEmitter&amp;lt;string&amp;gt;();
  searchTerm: string = '';
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Item Component (item.component.ts)&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;&amp;lt;!-- item.component.html --&amp;gt;
&amp;lt;h3&amp;gt;{{ item.title }}&amp;lt;/h3&amp;gt;
&amp;lt;p&amp;gt;{{ item.description }}&amp;lt;/p&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// item.component.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-item',
  templateUrl: './item.component.html',
})
export class ItemComponent {
  @Input() item: any;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Item List Component (item-list.component.ts)&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;&amp;lt;!-- item-list.component.html --&amp;gt;
&amp;lt;div *ngFor="let item of items"&amp;gt;
  &amp;lt;app-item [item]="item"&amp;gt;&amp;lt;/app-item&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// item-list.component.ts
import { Component, Input } from '@angular/core';

@Component({
  selector: 'app-item-list',
  templateUrl: './item-list.component.html',
})
export class ItemListComponent {
  @Input() items: any[] = [];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Updated Main Component (main.component.ts)&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;&amp;lt;!-- main.component.html --&amp;gt;
&amp;lt;app-search-bar (search)="searchTerm = $event"&amp;gt;&amp;lt;/app-search-bar&amp;gt;
&amp;lt;app-item-list [items]="filterItems(items, searchTerm)"&amp;gt;&amp;lt;/app-item-list&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// main.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-main',
  templateUrl: './main.component.html',
})
export class MainComponent {
  items = [
    { title: 'Item 1', description: 'Description of Item 1' },
    { title: 'Item 2', description: 'Description of Item 2' },
    { title: 'Item 3', description: 'Description of Item 3' }
  ];
  searchTerm = '';

  filterItems(items: any[], term: string) {
    return items.filter((item) =&amp;gt; item.title.includes(term));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Break Large Components?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;- Easier to Debug &amp;amp; Maintain&lt;/strong&gt; — Smaller components mean fewer things can go wrong. If a bug appears, it’s easier to isolate and fix.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Better Code Organization&lt;/strong&gt; — Each component handles one task, making the project easier to navigate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Better Reusability&lt;/strong&gt; — Extracting common UI elements prevents duplicate code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Improved Readability&lt;/strong&gt; — Smaller files are easier to navigate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Faster Testing&lt;/strong&gt; — Unit testing becomes much simpler because each component has a single purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Documenting code
&lt;/h2&gt;

&lt;p&gt;Documenting code with comments is an excellent practice, because it improves code maintainability, readability, and collaboration, making it easier for new developers (or even yourself in the future) to understand the logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1: Documenting a Method&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;/**
 * This method converts a given age into a string.
 * It takes a number as input and returns the string version of it.
 * 
 * @param age The age value to be converted.
 * @returns A string representation of the age value.
 */
function getAge(age: number): string {
  return age.toString();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example 2: Documenting a Variable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For class variables, documenting them can also be helpful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class UserProfile {
  /**
   * The name of the user.
   * This is typically initialized when the user registers.
   * @example "John Doe"
   */
  userName: string;

  /**
   * The age of the user in years.
   * This is an optional field and may not be available for every user.
   * @example 28
   */
  userAge?: number;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Angular Example: Documenting a Service Method&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In Angular services, you can document methods as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Injectable({
  providedIn: 'root'
})
export class UserService {
  /**
   * Fetches user data from the backend API.
   * It sends a GET request to retrieve the user's profile information.
   * 
   * @param userId The ID of the user whose data is to be fetched.
   * @returns An Observable of the user's data.
   */
  getUserData(userId: string): Observable&amp;lt;User&amp;gt; {
    return this.http.get&amp;lt;User&amp;gt;(`/api/users/${userId}`);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using clear, consistent commenting practices like this will make your code much more understandable.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Keep components lean by delegating complex logic to services.
&lt;/h2&gt;

&lt;p&gt;In Angular, components and templates serve distinct roles in the app architecture.&lt;/p&gt;

&lt;p&gt;The general rule is: components handle the logic, and templates handle the view. However, to avoid bloating your components with too much logic, it’s best to delegate business logic to services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Without a Service (Bad Practice)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here, the component is doing too much.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';

@Component({
  selector: 'app-products',
  template: `&amp;lt;div *ngFor="let product of products"&amp;gt;{{ product.name }}&amp;lt;/div&amp;gt;`,
})
export class ProductsComponent {
  products = [
    { id: 1, name: 'Jacket' },
    { id: 2, name: 'Sneakers' },
  ];

  filterProducts(search: string) {
    return this.products.filter(product =&amp;gt; product.name.includes(search));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The filtering logic should be handled by a service instead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: With a Service (Good Practice)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Move the logic to a service and inject it into the component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create the Service&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;import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root',
})
export class ProductService {
  private products = [
    { id: 1, name: 'Jacket' },
    { id: 2, name: 'Sneakers' },
  ];

  getProducts() {
    return this.products;
  }

  filterProducts(search: string) {
    return this.products.filter(product =&amp;gt; product.name.includes(search));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Use the Service in the Component&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;import { Component } from '@angular/core';
import { ProductService } from '../services/product.service';

@Component({
  selector: 'app-products',
  template: `&amp;lt;div *ngFor="let product of filteredProducts"&amp;gt;{{ product.name }}&amp;lt;/div&amp;gt;`,
})
export class ProductsComponent {
  filteredProducts = [];

  constructor(private productService: ProductService) {
    this.filteredProducts = this.productService.getProducts();
  }

  searchProducts(search: string) {
    this.filteredProducts = this.productService.filterProducts(search);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Delegate Logic to Services?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;- Separation of Concerns&lt;/strong&gt; — The component handles UI, and the service handles logic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Reusability&lt;/strong&gt; — ProductService can be used in multiple components.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Testability&lt;/strong&gt; — We can test the service separately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Maintainability&lt;/strong&gt; — Easier to modify or expand.&lt;/p&gt;

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

&lt;p&gt;By applying these best practices, your Angular applications will be more efficient, maintainable, and scalable.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>frontend</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Common Security Vulnerabilities in Angular Applications and How to Fix Them</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Wed, 26 Mar 2025 10:36:43 +0000</pubDate>
      <link>https://dev.to/bytebantz/common-security-vulnerabilities-in-angular-applications-and-how-to-fix-them-4055</link>
      <guid>https://dev.to/bytebantz/common-security-vulnerabilities-in-angular-applications-and-how-to-fix-them-4055</guid>
      <description>&lt;p&gt;In this article, we’ll explore common security issues in Angular applications, how attackers exploit them, and how to secure your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Cross-Site Scripting (XSS)
&lt;/h2&gt;

&lt;p&gt;XSS occurs when an application allows malicious scripts to execute in the browser.&lt;/p&gt;

&lt;p&gt;Angular sanitization is a built-in mechanisms that checks untrusted content and ensures it’s safe for the DOM.&lt;/p&gt;

&lt;p&gt;Angular cleans HTML by removing dangerous tags like &amp;lt;script&amp;gt;, blocks unsafe URLs (javascript: schemes), and prevents harmful CSS.&lt;/p&gt;

&lt;p&gt;Angular automatically sanitizes values bound [innerHTML], &amp;lt;a [href]&amp;gt;, &amp;lt;img [src]&amp;gt;, and [style] to protect your app.&lt;/p&gt;

&lt;p&gt;However, you can still introduce vulnerabilities if you &lt;strong&gt;intentionally bypass&lt;/strong&gt; security mechanisms or &lt;strong&gt;manipulate the DOM directly&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here are some examples of vulnerable code:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerability 1: Using bypassSecurityTrustHtml Unsafely&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;bypassSecurityTrustHtml&lt;/strong&gt; method forces Angular to trust the provided HTML, including unsafe content like &amp;lt;script&amp;gt; tags.&lt;/p&gt;

&lt;p&gt;Angular’s DomSanitizer can be misused to allow malicious scripts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerable Code:&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;import { Component } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

@Component({
  selector: 'app-inner-html-binding',
  template: `&amp;lt;div [innerHTML]="trustedHtmlSnippet"&amp;gt;&amp;lt;/div&amp;gt;`,
})
export class InnerHtmlBindingComponent {
  trustedHtmlSnippet: SafeHtml;

  constructor(private sanitizer: DomSanitizer) {
    const potentiallyUnsafe = 'Template &amp;lt;script&amp;gt;alert("0wned")&amp;lt;/script&amp;gt;';
    this.trustedHtmlSnippet = this.sanitizer.bypassSecurityTrustHtml(potentiallyUnsafe);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Safer Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of bypassing security, let Angular sanitize the HTML automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';

@Component({
  selector: 'app-inner-html-binding',
  template: `&amp;lt;div [innerHTML]="safeHtmlSnippet"&amp;gt;&amp;lt;/div&amp;gt;`,
})
export class InnerHtmlBindingComponent {
  safeHtmlSnippet = 'Template &amp;lt;script&amp;gt;alert("0wned")&amp;lt;/script&amp;gt;'; // Angular will sanitize this automatically
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Vulnerability 2: Directly Manipulating the DOM (ElementRef)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Angular’s built-in XSS protection &lt;strong&gt;only works in templates&lt;/strong&gt;, but &lt;strong&gt;direct DOM manipulation bypasses it&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Using ElementRef and innerHTML allows unsafe content insertion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerable Code:&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;import { Component, ElementRef, ViewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-root',
  imports: [FormsModule],
  template: `
    &amp;lt;input [(ngModel)]="comment" placeholder="Enter your comment"&amp;gt;
    &amp;lt;button (click)="postComment()"&amp;gt;Post Comment&amp;lt;/button&amp;gt;
    &amp;lt;div #commentBox&amp;gt;&amp;lt;/div&amp;gt;
  `,
})
export class AppComponent {
  @ViewChild('commentBox', { static: true }) commentBox!: ElementRef;
  comment: string = '';

  postComment() {
    this.commentBox.nativeElement.innerHTML = this.comment; // ⚠ Vulnerable to XSS!
  }
}

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

&lt;/div&gt;



&lt;p&gt;By default, modern browsers &lt;strong&gt;block&lt;/strong&gt; scripts inserted via innerHTML (they won't execute &amp;lt;script&amp;gt; tags).&lt;/p&gt;

&lt;p&gt;However, attackers can still exploit XSS &lt;strong&gt;without&lt;/strong&gt; using &amp;lt;script&amp;gt; tags by injecting &lt;strong&gt;malicious event handlers&lt;/strong&gt; like &lt;strong&gt;onerror&lt;/strong&gt;, &lt;strong&gt;onclick&lt;/strong&gt;, or &lt;strong&gt;onmouseover&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;&amp;lt;img src="x" onerror="alert('Hacked!')"&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Since the app is &lt;strong&gt;directly inserting user input into the DOM&lt;/strong&gt;, if a user submits the comment above, the &amp;lt;img&amp;gt; tag loads, fails (because src="x" is invalid), and &lt;strong&gt;triggers the onerror JavaScript&lt;/strong&gt;, showing an alert box. This is a &lt;strong&gt;Cross-Site Scripting (XSS) attack&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix: Use Angular’s Sanitization&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To avoid XSS, use [innerHTML] instead of ElementRef.innerHTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';

@Component({
  selector: 'app-root',
  imports: [FormsModule],
  template: `
    &amp;lt;input [(ngModel)]="comment" placeholder="Enter your comment"&amp;gt;
    &amp;lt;button (click)="postComment()"&amp;gt;Post Comment&amp;lt;/button&amp;gt;
    &amp;lt;div [innerHTML]="safeComment"&amp;gt;&amp;lt;/div&amp;gt;
  `,
})
export class AppComponent {
  comment: string = '';
  safeComment: string = '';

  postComment() {
    this.safeComment = this.comment; // Angular sanitizes input automatically
  }
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Clickjacking
&lt;/h2&gt;

&lt;p&gt;Clickjacking is when someone tricks you into clicking on something different from what you think you're clicking on.&lt;/p&gt;

&lt;p&gt;For example, they might overlay a malicious button on top of a legitimate one, so when you click, you're actually interacting with something you didn't intend to.&lt;/p&gt;

&lt;p&gt;Attackers can embed your Angular app inside an &amp;lt;iframe&amp;gt; and overlay a fake UI to steal user inputs.&lt;/p&gt;

&lt;p&gt;To check if your website can be embedded in an &amp;lt;iframe&amp;gt;, create an &lt;strong&gt;HTML file&lt;/strong&gt; (e.g., clickjack-test.html) and add this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;iframe src="https://your-angular-app.com" width="800" height="600"&amp;gt;&amp;lt;/iframe&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example of Clickjacking in Action:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The Fake Job Ad&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A scammer creates a webpage claiming:
&lt;em&gt;"Earn $500 per day! Click below to apply!"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;This &lt;strong&gt;fake ad&lt;/strong&gt; targets people searching for jobs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. The Clickjacking Trick&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The fake page &lt;strong&gt;loads a real job posting inside an invisible iframe&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;hidden "Like" or "Follow" button&lt;/strong&gt; is &lt;strong&gt;placed over the real "Apply Now" button&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;When the user clicks "Apply Now," they actually &lt;strong&gt;like or follow a scam page&lt;/strong&gt; instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. The Redirection to Avoid Suspicion&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After the &lt;strong&gt;hidden click happens&lt;/strong&gt;, the user is &lt;strong&gt;redirected to the real job listing&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The victim &lt;strong&gt;sees a legitimate job post&lt;/strong&gt;, making them think everything is normal.&lt;/li&gt;
&lt;li&gt;They never realize they just followed a scam page!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why Scammers Use Clickjacking:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They collect thousands of likes or follows for credibility.&lt;/li&gt;
&lt;li&gt;They post fake job offers to lure victims.&lt;/li&gt;
&lt;li&gt;Users click on scam links, thinking they are real opportunities.&lt;/li&gt;
&lt;li&gt;Some are tricked into paying fake "registration fees."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Secure Fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Angular does not have a specific built-in mechanism solely dedicated to preventing clickjacking out of the box.&lt;/p&gt;

&lt;p&gt;Set X-Frame-Options and Content-Security-Policy headers in the &lt;strong&gt;backend&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;X-Frame-Options: DENY
Content-Security-Policy: frame-ancestors 'none';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents clickjacking by blocking the site from being embedded in iframes.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Cross-Site Request Forgery (CSRF)
&lt;/h2&gt;

&lt;p&gt;CSRF is an attack where a malicious website tricks a user's browser into sending unintended requests to a different website where the user is authenticated.&lt;/p&gt;

&lt;p&gt;CSRF attacks are possible because web browsers automatically include cookies, including session cookies that contain authentication information, in every request&lt;/p&gt;

&lt;p&gt;If the server does not &lt;strong&gt;validate the request properly&lt;/strong&gt; (e.g., &lt;strong&gt;checking for an anti-CSRF token&lt;/strong&gt; or &lt;strong&gt;validating the Origin header&lt;/strong&gt;), an attacker can still trick a logged-in user into making unintended changes.&lt;/p&gt;

&lt;p&gt;Imagine you have an account on &lt;strong&gt;FastPizza&lt;/strong&gt; (&lt;a href="https://fastpizza.com" rel="noopener noreferrer"&gt;https://fastpizza.com&lt;/a&gt;), where you order food regularly.&lt;/p&gt;

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

&lt;p&gt;You log in and go to &lt;strong&gt;Settings → Change Email&lt;/strong&gt;, where you enter a new email.&lt;br&gt;&lt;br&gt;
The website sends this request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST https://fastpizza.com/update-email
Content-Type: application/x-www-form-urlencoded

email=mynewemail@example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The Attack (CSRF Exploit)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You are already logged into &lt;strong&gt;FastPizza&lt;/strong&gt; in one tab.&lt;br&gt;&lt;br&gt;
You then visit a &lt;strong&gt;malicious website&lt;/strong&gt;, maybe a recipe blog or a free giveaway site.&lt;/p&gt;

&lt;p&gt;The hacker &lt;strong&gt;creates this hidden form&lt;/strong&gt; into the page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;form action="https://fastpizza.com/update-email" method="POST"&amp;gt;
    &amp;lt;input type="hidden" name="email" value="hacker@example.com"&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;script&amp;gt;
    document.forms[0].submit(); // Automatically submits the form when the victim visits
&amp;lt;/script&amp;gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If the victim is &lt;strong&gt;logged in&lt;/strong&gt;, their session cookie is sent automatically.&lt;/li&gt;
&lt;li&gt;The server processes the request and updates the email without any additional verification.&lt;/li&gt;
&lt;li&gt;Now, the attacker's email is linked to the victim’s account.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Secure Fix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use &lt;strong&gt;CSRF tokens&lt;/strong&gt; in HTTP requests:&lt;/p&gt;

&lt;p&gt;Angular's HttpClient helps prevent these attacks using a &lt;strong&gt;token system&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The backend server &lt;strong&gt;creates a special security token&lt;/strong&gt; (usually named XSRF-TOKEN) and stores it in a &lt;strong&gt;cookie&lt;/strong&gt; when the user loads the page.&lt;/li&gt;
&lt;li&gt;Angular &lt;strong&gt;automatically reads&lt;/strong&gt; this token and includes it in the request headers under X-XSRF-TOKEN.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If it’s &lt;strong&gt;not working automatically&lt;/strong&gt;, create an &lt;strong&gt;Interceptor&lt;/strong&gt; to manually extract the token.&lt;/p&gt;

&lt;p&gt;3.The backend &lt;strong&gt;checks if the request contains a valid token&lt;/strong&gt; before allowing it to change data.&lt;/p&gt;

&lt;p&gt;If your backend &lt;strong&gt;uses different token names&lt;/strong&gt;, you can configure Angular to use them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provideHttpClient(
  withXsrfConfiguration({
    cookieName: 'CUSTOM_XSRF_TOKEN',
    headerName: 'X-Custom-Xsrf-Header',
  }),
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. DOM Clobbering
&lt;/h2&gt;

&lt;p&gt;DOM Clobbering is an attack where an attacker manipulates the &lt;strong&gt;DOM properties&lt;/strong&gt; to override JavaScript variables or elements, causing unintended behavior.&lt;/p&gt;

&lt;p&gt;Imagine a user is trying to &lt;strong&gt;update their password&lt;/strong&gt; on a website. If the frontend is vulnerable to &lt;strong&gt;DOM Clobbering&lt;/strong&gt;, an attacker can &lt;strong&gt;inject their own password&lt;/strong&gt;, causing the victim’s password to be changed to one controlled by the attacker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerable Code:&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;&amp;lt;form id="updatePasswordForm"&amp;gt;
  &amp;lt;input type="password" name="newPassword" placeholder="Enter new password" /&amp;gt;
  &amp;lt;input type="password" name="confirmPassword" placeholder="Confirm new password" /&amp;gt;
  &amp;lt;button type="submit"&amp;gt;Update Password&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;

&amp;lt;script&amp;gt;
  const newPasswordInput = document.querySelector('input[name="newPassword"]');

  document.getElementById('updatePasswordForm').addEventListener('submit', function(event) {
    event.preventDefault();
    console.log('Updating password to:', newPasswordInput.value);
  });
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Malicious Injection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An attacker injects the following malicious hidden input field into the page:&lt;/p&gt;

&lt;p&gt;Since &lt;strong&gt;JavaScript automatically associates elements with global variables&lt;/strong&gt;, document.getElementById('newPassword') &lt;strong&gt;now points to the hidden field instead of the real input&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of their chosen password, "hackedPassword123" is sent to the server.&lt;/p&gt;

&lt;p&gt;The attacker can now log in using the victim’s account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Secure Fix Using Angular Reactive Forms&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To prevent this attack, avoid querySelector() and use &lt;strong&gt;Angular’s Form Controls&lt;/strong&gt; to securely reference inputs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component } from '@angular/core';
import { ReactiveFormsModule, FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    &amp;lt;form [formGroup]="passwordForm" (ngSubmit)="onSubmit()"&amp;gt;
      &amp;lt;input type="password" formControlName="newPassword" placeholder="Enter new password"&amp;gt;
      &amp;lt;input type="password" formControlName="confirmPassword" placeholder="Confirm new password"&amp;gt;
      &amp;lt;button type="submit"&amp;gt;Update Password&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
  `,
})
export class AppComponent {
  passwordForm = new FormGroup({
    newPassword: new FormControl('', [Validators.required]),
    confirmPassword: new FormControl('', [Validators.required])
  });

  onSubmit() {
    console.log('Updating password to:', this.passwordForm.get('newPassword')?.value);
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;By understanding these vulnerabilities and implementing Angular’s built-in security mechanisms and recommended practices, developers can significantly enhance the security posture of their applications.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Design Patterns Every Angular Developer Should Know</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Mon, 24 Mar 2025 17:25:13 +0000</pubDate>
      <link>https://dev.to/bytebantz/design-patterns-every-angular-developer-should-know-4llf</link>
      <guid>https://dev.to/bytebantz/design-patterns-every-angular-developer-should-know-4llf</guid>
      <description>&lt;p&gt;New developers might not consider how the code will handle future changes or how easily it can be reused, expanded, or maintained. In the worst-case scenario, developers might even need to completely rebuild the project from scratch when things become too hard to fix. To avoid these issues, &lt;strong&gt;design patterns&lt;/strong&gt; were created.&lt;/p&gt;

&lt;p&gt;Design patterns are like blueprints that make your code easier to manage and change over time.&lt;/p&gt;

&lt;p&gt;Design patterns are tried-and-tested solutions for common design issues in software development. Instead of giving a full solution, they act as best practices for solving common software design challenges.&lt;/p&gt;

&lt;p&gt;Design patterns in Angular help you write cleaner, more organized code that makes your app easier to build, grow, and fix over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Design Patterns are important
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Scalability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Design Patterns help break your app into small, reusable pieces. This makes it easy to add new features later without messing up existing ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Maintainability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Following design patterns ensures your code has a clear, organized structure.&lt;/p&gt;

&lt;p&gt;For example using patterns like the &lt;strong&gt;Singleton Pattern&lt;/strong&gt; makes the app more maintainable because you only have to change one piece of code in the service, and all the components that depend on it will automatically adapt.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Testability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Design patterns promotes the separation of concerns which makes it easier to mock and test components&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Code Reusability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Patterns encourage writing reusable code.&lt;/p&gt;

&lt;p&gt;For example, patterns like &lt;strong&gt;Factory&lt;/strong&gt; and &lt;strong&gt;Singleton&lt;/strong&gt; help you organize similar tasks in one place, so you can easily reuse them without rewriting the same logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Singleton Pattern
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Singleton Pattern&lt;/strong&gt; ensures that a class only has &lt;strong&gt;one instance&lt;/strong&gt; and allows that instance to be &lt;strong&gt;shared&lt;/strong&gt; globally.&lt;/p&gt;

&lt;p&gt;In Angular, this is often used for &lt;strong&gt;services&lt;/strong&gt;, making sure only one instance of a service is used throughout the app.&lt;/p&gt;

&lt;p&gt;A service becomes a singleton when it's provided at the &lt;strong&gt;root level&lt;/strong&gt;. To do this, you use the &lt;strong&gt;providedIn: 'root'&lt;/strong&gt; setting in the service’s metadata.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root' // This makes the service a singleton
})
export class MyService {
  constructor() { }

  // Your service methods here
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Facade Pattern
&lt;/h2&gt;

&lt;p&gt;The Facade Pattern offers a &lt;strong&gt;simplified interface&lt;/strong&gt; to interact with complex subsystems.&lt;/p&gt;

&lt;p&gt;When you don’t use the &lt;strong&gt;Facade Pattern,&lt;/strong&gt; components directly communicate with multiple services to handle different operations. This increases complexity as multiple components may replicate the same logic, leading to code duplication.&lt;/p&gt;

&lt;p&gt;With the &lt;strong&gt;Facade Pattern&lt;/strong&gt; instead of components calling multiple services, they interact with the facade. This makes the components leaner and easier to maintain, while business logic remains in one centralized place (the facade)&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Injectable({
  providedIn: 'root',
})
export class CartFacade {
  constructor(private cartService: CartService, private orderService: OrderService) {}

  // Add product to cart
  addToCart(product: Product) {
    this.cartService.addItem(product);
  }

  // Remove product from cart
  removeFromCart(product: Product) {
    this.cartService.removeItem(product);
  }

  // Process checkout using the current cart
  checkout() {
    const cart = this.cartService.getCart();
    this.orderService.processOrder(cart);
  }

  // Get the current items in the cart
  getCartItems() {
    return this.cartService.getCart();
  }
}

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

&lt;/div&gt;



&lt;p&gt;To use the &lt;strong&gt;Facade Pattern&lt;/strong&gt; in your Angular components, you simply &lt;strong&gt;inject the facade service&lt;/strong&gt; into the component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor(private cartFacade: CartFacade) {}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Factory Pattern
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Factory Pattern&lt;/strong&gt; is a way of creating objects without specifying the exact class of the object that will be created.&lt;/p&gt;

&lt;p&gt;It handles the object creation process and conceals the details of how instances are instantiated.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Factory Pattern&lt;/strong&gt; can create objects dynamically, which is useful of you don’t know in advance the exact objects/services your application will need at runtime&lt;/p&gt;

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

&lt;p&gt;Let's say you want to create different types of user notifications (e.g., &lt;strong&gt;email&lt;/strong&gt;, &lt;strong&gt;SMS&lt;/strong&gt;). You can implement the &lt;strong&gt;Factory Pattern&lt;/strong&gt; as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// src/app/notification.interface.ts // src/app/notification.interface.ts
export interface Notification {
  send(message: string): void;
}

// src/app/notification.service.ts
import { Injectable } from '@angular/core';
import { Notification } from './notification.interface';

@Injectable({
  providedIn: 'root',
})
export class EmailNotification implements Notification {
  send(message: string): void {
    console.log(`Email: ${message}`);
  }
}

@Injectable({
  providedIn: 'root',
})
export class SmsNotification implements Notification {
  send(message: string): void {
    console.log(`SMS: ${message}`);
  }
}

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

&lt;/div&gt;



&lt;p&gt;Now, let’s create a &lt;strong&gt;factory&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;// src/app/notification.factory.ts
import { Injectable } from '@angular/core';
import { EmailNotification } from './notification.service';
import { SmsNotification } from './notification.service';
import { Notification } from './notification.interface';

@Injectable({
  providedIn: 'root',
})
export class NotificationFactory {
  constructor(
    private emailNotification: EmailNotification,
    private smsNotification: SmsNotification
  ) {}

  createNotification(type: string): Notification {
    if (type === 'email') {
      return this.emailNotification;
    } else if (type === 'sms') {
      return this.smsNotification;
    } else {
      throw new Error('Unknown notification type');
    }
  }
}

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

&lt;/div&gt;



&lt;p&gt;Now, in your component, you can use the &lt;strong&gt;factory&lt;/strong&gt; 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;// src/app/notification/notification.component.ts
import { Component } from '@angular/core';
import { NotificationFactory } from '../notification.factory';
import { Notification } from '../notification.interface';

@Component({
  selector: 'app-notification',
  template: `
    &amp;lt;h1&amp;gt;Send Notification&amp;lt;/h1&amp;gt;
    &amp;lt;button (click)="send('email')"&amp;gt;Send Email&amp;lt;/button&amp;gt;
    &amp;lt;button (click)="send('sms')"&amp;gt;Send SMS&amp;lt;/button&amp;gt;
  `,
})
export class NotificationComponent {
  constructor(private notificationFactory: NotificationFactory) {}

  send(type: string) {
    const notification: Notification = this.notificationFactory.createNotification(type);
    notification.send(`This is a ${type} notification!`);
  }
}

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Strategy Pattern
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Strategy Pattern&lt;/strong&gt; deals with behaviors (algorithms) and how they are used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strategy patterns&lt;/strong&gt; are useful when you need to switch between different algorithms or functionalities based on the context.&lt;/p&gt;

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

&lt;p&gt;This service will dynamically select the payment method based on the user’s choice.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Injectable({
  providedIn: 'root',
})
export class PaymentService {
  constructor(private paypalPayment: PayPalPayment, private creditCardPayment: CreditCardPayment) {}

  processPayment(method: 'paypal' | 'creditcard', amount: number): string {
    if (method === 'paypal') {
      return this.paypalPayment.processPayment(amount);
    } else {
      return this.creditCardPayment.processPayment(amount);
    }
  }
}

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

&lt;/div&gt;



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

&lt;p&gt;Design patterns provide crucial benefits in terms of scalability, maintainability, testability, and code reusability. In Angular, using patterns like Singleton, Facade, Factory, and Strategy will help you build applications that are easier to manage and expand. These patterns are essential for any large or growing application where clean, organized, and maintainable code is a priority.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Understanding :host and :host-context in Angular Styling</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Mon, 24 Mar 2025 12:37:39 +0000</pubDate>
      <link>https://dev.to/bytebantz/understanding-host-and-host-context-in-angular-styling-2b9n</link>
      <guid>https://dev.to/bytebantz/understanding-host-and-host-context-in-angular-styling-2b9n</guid>
      <description>&lt;p&gt;When styling Angular components, you can’t simply target them using standard CSS selectors like you would with regular HTML elements. Instead, Angular provides special selectors like &lt;strong&gt;:host&lt;/strong&gt; and &lt;strong&gt;:host-context&lt;/strong&gt; to help style components effectively.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is :host?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;:host&lt;/strong&gt; selector is a special CSS rule in Angular that allows you to apply styles to the &lt;strong&gt;root element&lt;/strong&gt; of a component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why do we need it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Normally, in CSS, you can target elements directly. But in Angular, components are custom elements, and you &lt;strong&gt;cannot&lt;/strong&gt; style them the usual way.&lt;/p&gt;

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

&lt;p&gt;Let’s say we are building a &lt;strong&gt;User Profile Card&lt;/strong&gt; component in Angular.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;app-user-card&amp;gt;
    &amp;lt;img src="profile.jpg" alt="User Photo"&amp;gt;
    &amp;lt;h3&amp;gt;John Doe&amp;lt;/h3&amp;gt;
    &amp;lt;p&amp;gt;Web Developer&amp;lt;/p&amp;gt;
&amp;lt;/app-user-card&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;If we try to add a border to this &lt;em&gt;app-user-card&lt;/em&gt; in the component's CSS file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app-user-card {
    border: 2px solid black;
    padding: 10px;
}

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

&lt;/div&gt;



&lt;p&gt;👉 This will &lt;strong&gt;not work&lt;/strong&gt; because &lt;em&gt;app-user-card&lt;/em&gt; is an Angular component and not a standard HTML element.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution: Use :host&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We can use &lt;strong&gt;:host&lt;/strong&gt; to target the root element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:host {
  display: block;
  border: 2px solid black;
  border-radius: 0.375em;
  background-color: #eee;
}

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

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Now, the styles apply to the root element of the&lt;/strong&gt; &lt;em&gt;app-user-card&lt;/em&gt; &lt;strong&gt;component.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conditional Styling Using :host(.class-name)
&lt;/h2&gt;

&lt;p&gt;Sometimes, you only want to apply styles when the component has a certain class.&lt;/p&gt;

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

&lt;p&gt;Imagine we want to highlight &lt;strong&gt;premium users&lt;/strong&gt; with a golden border.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;app-user-card class="premium"&amp;gt;
    &amp;lt;img src="profile.jpg" alt="User Photo"&amp;gt;
    &amp;lt;h3&amp;gt;Jane Smith&amp;lt;/h3&amp;gt;
    &amp;lt;p&amp;gt;Premium Member&amp;lt;/p&amp;gt;
&amp;lt;/app-user-card&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Now, in our component's CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:host(.premium) {
    display: block;
    border: 2px solid gold;
    border-radius: 0.375em;
    background-color: #eee;
}

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

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Now, these styles apply only when the premium class is present on&lt;/strong&gt; &lt;em&gt;app-user-card&lt;/em&gt;&lt;strong&gt;&lt;em&gt;.&lt;/em&gt;&lt;/strong&gt; If we remove the &lt;strong&gt;class="premium",&lt;/strong&gt; the styles won’t apply.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is :host-context?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;:host-context&lt;/strong&gt; selector allows us to apply styles &lt;strong&gt;based on where the component is used&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;:host-context(selector)&lt;/strong&gt; applies styles only when the component is inside an element matching the given selector.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using :host-context&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine your site has a &lt;strong&gt;Dark Mode&lt;/strong&gt; &lt;strong&gt;feature&lt;/strong&gt;. You want all &lt;strong&gt;User Profile Cards&lt;/strong&gt; to look different when inside a &lt;strong&gt;&lt;em&gt;dark-mode&lt;/em&gt;&lt;/strong&gt; container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="dark-mode"&amp;gt;
    &amp;lt;app-user-card&amp;gt;
        &amp;lt;img src="profile.jpg" alt="User Photo"&amp;gt;
        &amp;lt;h3&amp;gt;Sarah Connor&amp;lt;/h3&amp;gt;
        &amp;lt;p&amp;gt;Graphic Designer&amp;lt;/p&amp;gt;
    &amp;lt;/app-user-card&amp;gt;
&amp;lt;/div&amp;gt;

:host-context(.dark-mode) {
    display: block;
    border: 2px solid gray;
    border-radius: 0.375em;
    background-color: #333;
    color: white;
}

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

&lt;/div&gt;



&lt;p&gt;✅ &lt;strong&gt;Now, if app-user-card is inside .dark-mode, it automatically changes to dark mode!&lt;/strong&gt; 🌙&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Problem with :host-context()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While &lt;strong&gt;:host-context&lt;/strong&gt;() is useful, it can cause &lt;strong&gt;tight coupling&lt;/strong&gt; between components and global styles.&lt;/p&gt;

&lt;p&gt;If you rename &lt;strong&gt;.dark-mode&lt;/strong&gt; to &lt;strong&gt;.theme-dark&lt;/strong&gt;, you must update &lt;strong&gt;every&lt;/strong&gt; component using &lt;strong&gt;:host-context(.dark-mode).&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A Better Alternative: Use CSS Variables Instead of &lt;strong&gt;:&lt;/strong&gt;host-context()
&lt;/h2&gt;

&lt;p&gt;Instead of &lt;strong&gt;:host-context(),&lt;/strong&gt; we can use &lt;strong&gt;CSS variables&lt;/strong&gt; that change based on a global class.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CSS variables&lt;/strong&gt; are a powerful way to &lt;strong&gt;manage&lt;/strong&gt; and &lt;strong&gt;centralize&lt;/strong&gt; styling properties in CSS.&lt;/p&gt;

&lt;p&gt;Here's how they work:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ Step 1: Define Global Theme Variables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;CSS variables are defined with a &lt;strong&gt;-- prefix&lt;/strong&gt; followed by &lt;strong&gt;a&lt;/strong&gt; &lt;strong&gt;name&lt;/strong&gt; and &lt;strong&gt;a&lt;/strong&gt; &lt;strong&gt;value&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;:root&lt;/strong&gt; pseudo-class is commonly used to &lt;strong&gt;define these variables globally&lt;/strong&gt;, making them accessible &lt;strong&gt;throughout&lt;/strong&gt; the application.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* styles.css */
:root {
  --bg-color: white;
  --text-color: black;
}

.dark-mode {
  --bg-color: black;
  --text-color: white;
}

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;✅ Step 2: Apply Variables in Components&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To use a CSS variable, you use the &lt;strong&gt;var()&lt;/strong&gt; function, passing the variable name as an argument.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:host {
  background-color: var(--bg-color);
  color: var(--text-color);
  display: block;
  border: 2px solid gray;
  border-radius: 0.375em;
}

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

&lt;/div&gt;



&lt;p&gt;Now, components will &lt;strong&gt;automatically adjust&lt;/strong&gt; without relying on &lt;strong&gt;:host-context().&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to explore&amp;nbsp;more?
&lt;/h2&gt;

&lt;p&gt;Check out my &lt;strong&gt;&lt;a href="https://bytebantz.gumroad.com/l/kufka" rel="noopener noreferrer"&gt;deep dive on Angular styling techniques&lt;/a&gt;&lt;/strong&gt; on Gumroad for additional insights and best practices! → &lt;a href="https://bytebantz.gumroad.com" rel="noopener noreferrer"&gt;https://bytebantz.gumroad.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>angular</category>
      <category>softwaredevelopment</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Your Data, Your Privacy: How VPNs Hide Your Identity</title>
      <dc:creator>bytebantz</dc:creator>
      <pubDate>Sat, 28 Dec 2024 10:25:05 +0000</pubDate>
      <link>https://dev.to/bytebantz/your-data-your-privacy-how-vpns-hide-your-identity-4b08</link>
      <guid>https://dev.to/bytebantz/your-data-your-privacy-how-vpns-hide-your-identity-4b08</guid>
      <description>&lt;h2&gt;
  
  
  What is a VPN?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;VPN&lt;/strong&gt; (Virtual Private Network) is a service that encrypts your internet connection and routes it through a secure server, masking your real IP address. By doing so, it ensures that your online activities remain private and your data is secure, even on public networks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Use a VPN?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Enhanced Privacy&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Without a &lt;strong&gt;VPN&lt;/strong&gt;, websites, &lt;strong&gt;ISPs&lt;/strong&gt; (Internet Service Providers), and other entities can track your IP address, browsing habits, and location. A &lt;strong&gt;VPN&lt;/strong&gt; hides this information, giving you greater anonymity.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Security on Public Wi-Fi&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Public Wi-Fi networks are hotspots for cybercriminals. A &lt;strong&gt;VPN&lt;/strong&gt; encrypts your connection, safeguarding your data from prying eyes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Bypassing Geo-Restrictions&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;VPNs&lt;/strong&gt; allow you to access content unavailable in your country by routing your connection through servers in different regions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Preventing ISP Throttling&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Some &lt;strong&gt;ISPs&lt;/strong&gt; monitor your online activities and slow down your connection based on usage. A &lt;strong&gt;VPN&lt;/strong&gt; encrypts your traffic, preventing ISPs from selectively throttling your speeds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Online Banking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Some banks block access from foreign IP addresses to prevent fraud. A &lt;strong&gt;VPN&lt;/strong&gt; allows you to appear as if you're accessing the internet from your home country by routing your connection through a &lt;strong&gt;VPN&lt;/strong&gt; server in your home country.&lt;/p&gt;

&lt;p&gt;To grasp how &lt;strong&gt;VPNs&lt;/strong&gt; work, it's helpful to understand some fundamental networking concepts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Network Interface Card (NIC):&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The &lt;strong&gt;NIC&lt;/strong&gt; is the hardware in your computer or device that enables network connectivity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Wired NICs&lt;/strong&gt; use Ethernet cables to connect directly to a network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wireless NICs&lt;/strong&gt; connect to Wi-Fi networks without cables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without a &lt;strong&gt;NIC&lt;/strong&gt;, your device cannot access the internet, making it a critical component for &lt;strong&gt;VPN&lt;/strong&gt; functionality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Network Address Translation (NAT):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NAT&lt;/strong&gt; (Network Address Translation) is a method used by routers to map multiple private IP addresses to a single public IP address (or a few public IPs).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NAT&lt;/strong&gt; allows multiple devices on a private network to share a single public IP address, effectively managing limited public IP resources.&lt;/p&gt;

&lt;p&gt;Without &lt;strong&gt;NAT&lt;/strong&gt;, every device would need its own public IP address. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If a single household had 10 devices, it would need 10 public IPs.&lt;/li&gt;
&lt;li&gt;Multiply that by millions of households worldwide, and the demand for public IPs would far exceed supply.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;NAT&lt;/strong&gt; solves this problem by letting networks use private IPs internally and translating them to one or a few public IPs for external communication. This significantly reduces the number of public IPs required globally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. The Setup&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    Imagine you have a home network with 3 devices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Device A: Private IP 192.168.1.2&lt;/li&gt;
&lt;li&gt;Device B: Private IP 192.168.1.3&lt;/li&gt;
&lt;li&gt;Device C: Private IP 192.168.1.4
These private IPs are not unique and cannot be used on the internet. Instead, your Internet Service Provider (ISP) gives you &lt;strong&gt;one public IP&lt;/strong&gt;: 203.0.113.1.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Device Wants to Access the Internet&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    Suppose Device A wants to visit example.com (IP 93.184.216.34). It sends a request to the router with its private IP address:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source IP (Private)&lt;/strong&gt;: 192.168.1.2&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Destination IP (Public)&lt;/strong&gt;: 93.184.216.34.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. The Router Translates&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    The router receives the request and does two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Replaces the private IP (192.168.1.2) with the public IP (203.0.113.1)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Records the translation in a table&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Private IP  | Port    | Public IP       | Port
192.168.1.2 | 12345   | 203.0.113.1     | 54321
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, 12345 is the source port assigned by Device A, and 54321 is a new port the router assigns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. The Request Goes to the Internet&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    Now, the request sent to example.com looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source IP (Public)&lt;/strong&gt;: 203.0.113.1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source Port&lt;/strong&gt;: 54321&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Destination IP (Public)&lt;/strong&gt;: 93.184.216.34.
This makes it seem like the request is coming from the public IP, not Device A.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. Response Comes Back&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    The website example.com sends a response back to your public IP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Source IP&lt;/strong&gt;: 93.184.216.34&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Destination IP (Public)&lt;/strong&gt;: 203.0.113.1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Destination Port&lt;/strong&gt;: 54321.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6. Router Translates Back&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    The router checks its NAT table to match the public IP and port (203.0.113.1:54321) to the corresponding private IP and port (192.168.1.2:12345). It then forwards the response to Device A.&lt;br&gt;
&lt;strong&gt;7. Device A Gets the Data&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
    Device A receives the response, and the process is complete!&lt;/p&gt;

&lt;p&gt;VPNs add a layer of privacy to this setup by replacing your public IP with that of the VPN server, preventing websites and other entities from tracking your location and activities.&lt;/p&gt;

&lt;h2&gt;
  
  
  How a VPN works
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Establishing a Secure Tunnel&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When you enable a &lt;strong&gt;VPN&lt;/strong&gt;, it creates a secure and encrypted connection (a "tunnel") between your device and a &lt;strong&gt;VPN server&lt;/strong&gt; located elsewhere.&lt;/li&gt;
&lt;li&gt;Encryption ensures that any data traveling through this tunnel is scrambled and cannot be intercepted or read by unauthorized parties.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Sending Your Data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All your internet traffic (like requests to visit websites) is routed through this secure tunnel to the &lt;strong&gt;VPN server&lt;/strong&gt; instead of going directly to the internet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Decryption at the VPN Server&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The VPN server receives your encrypted data.&lt;/li&gt;
&lt;li&gt;It decrypts the data to understand your request (e.g., visiting a specific website).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Hiding Your IP Address&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The VPN server forwards your request to the website you're trying to access.&lt;/li&gt;
&lt;li&gt;The website does not see your actual IP address (your location). Instead, it sees the IP address of the VPN server, effectively hiding your real location.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Receiving the Website’s Response&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The website processes your request and sends the response (e.g., loading a webpage) back to the VPN server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Encrypting the Data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The VPN server encrypts the website's response and sends it back through the secure tunnel to your device.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 7: Decrypting and Displaying Data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your device receives the encrypted data from the VPN server.&lt;/li&gt;
&lt;li&gt;It decrypts the data, making it readable, and displays the content you requested (e.g., the webpage).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, some &lt;strong&gt;VPNs&lt;/strong&gt; may slow down your internet connection due to the extra step of routing traffic through a remote server. It's important to choose a &lt;strong&gt;VPN&lt;/strong&gt; that offers high-speed servers, especially if you plan on streaming or gaming.&lt;/p&gt;

&lt;p&gt;Some free VPNs may track and sell user data to advertisers, defeating the purpose of using a VPN in the first place. Always use a reputable paid service with no-logs policy, but remember that expensive doesn't necessarily equate to higher quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recommended Affiliate VPN Providers
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Surfshark&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why Choose Surfshark?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No-logs policy&lt;/strong&gt;: Surfshark's no-logs policy means that your online activities are never tracked or stored.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Servers&lt;/strong&gt;: Surfshark has over 3,200 servers, and its 100% RAM-only servers erase your data if the server is seized&lt;/li&gt;
&lt;li&gt;You can use one Surfshark account to secure every device you own that supports a VPN client.&lt;/li&gt;
&lt;li&gt;Surfshark offers advanced privacy features, including rotating IP and Dynamic MultiHop.&lt;/li&gt;
&lt;li&gt;Surfshark is considered to be competitively priced.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;NordVPN&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Why Choose NordVPN?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Large Server Network:&lt;/strong&gt; Access to a vast number of servers in multiple countries, over 5,500 servers worldwide, allowing for fast connections and diverse location options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced Security Features:&lt;/strong&gt; Utilizes industry-standard encryption protocols like AES-256 for maximum data protection.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dark Web Monitor&lt;/strong&gt;: Get instant alerts about leaked credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Threat Protection:&lt;/strong&gt; Additional feature to block malware, trackers, and malicious websites.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;strong&gt;VPNs&lt;/strong&gt; are essential for maintaining online privacy and security in today’s digital world. This article covered how &lt;strong&gt;VPNs&lt;/strong&gt; work, their benefits, and key networking concepts like &lt;strong&gt;NIC&lt;/strong&gt; and &lt;strong&gt;NAT&lt;/strong&gt; that facilitate secure and efficient connectivity. Whether you’re looking to safeguard your personal data, bypass geographical restrictions, or prevent ISP throttling, a &lt;strong&gt;VPN&lt;/strong&gt; is a great tool. With reliable options like Surfshark&lt;/p&gt;

</description>
      <category>networking</category>
      <category>vpn</category>
      <category>privacy</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
