<?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: Azad Shukor</title>
    <description>The latest articles on DEV Community by Azad Shukor (@azadshukor).</description>
    <link>https://dev.to/azadshukor</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%2F1035198%2F42ef8a08-4c61-40ae-b4f5-8497b4cb5316.jpeg</url>
      <title>DEV Community: Azad Shukor</title>
      <link>https://dev.to/azadshukor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/azadshukor"/>
    <language>en</language>
    <item>
      <title>Identity-Driven Premature Closure: The PR Review Trap I Fell Into Every Day</title>
      <dc:creator>Azad Shukor</dc:creator>
      <pubDate>Sat, 01 Aug 2026 05:09:15 +0000</pubDate>
      <link>https://dev.to/azadshukor/identity-driven-premature-closure-the-pr-review-trap-i-fell-into-every-day-30cb</link>
      <guid>https://dev.to/azadshukor/identity-driven-premature-closure-the-pr-review-trap-i-fell-into-every-day-30cb</guid>
      <description>&lt;p&gt;I review a PR. The diff is small. I scroll until something catches my eye:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've seen patterns like this before. Something about it feels off. A familiar irritation rises — this ticket has been reopened multiple times. The developer has a history of missed scenarios. I don't trace the callers. I don't pull the branch. I don't read the full function. I post:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why isn't this checking &lt;code&gt;.Data.name&lt;/code&gt; and returning 'anonymous'?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then I pull the code locally. I see the whole function — more lines, more context, the full shape. The logic becomes apparent. The guard clause is correct. The name replacement happens in the caller. The implementation follows best practice. I reply: "actually it is correct."&lt;/p&gt;

&lt;p&gt;No apology. Just embarrassment. Again.&lt;/p&gt;

&lt;p&gt;This happens on nearly every PR I review.&lt;/p&gt;

&lt;p&gt;I called this laziness. I was wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Science Behind It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  It's not laziness. It's identity-driven premature closure.
&lt;/h3&gt;

&lt;p&gt;Three mechanisms converge:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Need for Cognitive Closure
&lt;/h4&gt;

&lt;p&gt;In 1996, psychologist Arie Kruglanski defined the &lt;strong&gt;need for cognitive closure&lt;/strong&gt; as the desire for "an answer on a given topic, any answer… compared to confusion and ambiguity" (Kruglanski &amp;amp; Webster, &lt;em&gt;Psychological Review&lt;/em&gt;, 1996). It has two components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Urgency tendency ("seizing")&lt;/strong&gt;: the impulse to reach a conclusion as quickly as possible&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permanence tendency ("freezing")&lt;/strong&gt;: the impulse to hold onto that conclusion once reached&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I see unfamiliar code in a narrow diff window, I feel confusion. Confusion is uncomfortable. My brain wants it resolved — fast. I seize on the first familiar pattern (&lt;code&gt;return empty&lt;/code&gt; → "missing something"), freeze on it ("this is wrong"), and post.&lt;/p&gt;

&lt;p&gt;The discomfort drives the speed. The speed prevents correction.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Confirmation Bias in Code Review
&lt;/h4&gt;

&lt;p&gt;Devroey, Matton, and Vanderose (2024, &lt;em&gt;arXiv:2407.01407&lt;/em&gt;) studied cognitive biases in code review. They found that confirmation bias — searching for evidence that supports your pre-existing belief — is especially strong when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A reviewer identifies heavily with a "gatekeeper" role&lt;/li&gt;
&lt;li&gt;The reviewer enters the review with expectations about the author&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both apply to me. I believe my job is to find what's wrong. I enter reviews of repeatedly-reopened tickets with a pre-existing story: "this developer doesn't check all scenarios." I don't read the code neutrally. I read it looking for a confirmation of that story — and I find one.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Identity-Protective Cognition
&lt;/h4&gt;

&lt;p&gt;This is the deepest layer. Kunda (1990, &lt;em&gt;Psychological Bulletin&lt;/em&gt;) showed that when reasoning touches self-concept, people don't just make errors — they're &lt;em&gt;motivated&lt;/em&gt; to reach conclusions that protect their identity.&lt;/p&gt;

&lt;p&gt;My identity is organized around being the person who catches bugs. Catching a real bug "feels the best." Finding clean code triggers embarrassment — because if the code is clean, then what value did I add? The review becomes less about code quality and more about proving I'm competent.&lt;/p&gt;

&lt;p&gt;The quick criticism serves an identity function: it proves I'm doing my job. Even when it's wrong.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is the Proof?
&lt;/h2&gt;

&lt;p&gt;Here is the chain — mapped from my own answers under direct questioning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TRIGGER
  PR on a reopened ticket
  + Author with a bug history
  + Diff view that shows only fragments
        ↓
INTERNAL REACTION
  "Why is this still open?"
  + Identity activation: "I am the bug-catcher"
  + Irritation from missing context
        ↓
SHORTCUT
  Scroll until something familiar catches my eye
  + Familiarity feels like understanding (it isn't)
  + "I've been right before" → permission to trust my judgment
  + Skip: callers, tests, full function, pulling locally
        ↓
IMMEDIATE REWARD
  Temporary resolution of "what's my role?" anxiety
  + Relief from the discomfort of confusion
  + The possibility of that "best feeling" (catching a real bug)
        ↓
MISTAKE
  The code was correct. My criticism was based on a fragment.
  Flat retraction: "actually it is correct."
        ↓
LONG-TERM COST
  Embarrassment that compounds
  + Colleagues learn my reviews are unreliable
  + I model "criticize first, understand later"
  + I never practice reading unfamiliar code
  + Pattern repeats — every PR
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The evidence is in the pattern, not a single incident
&lt;/h3&gt;

&lt;p&gt;This isn't one bad review. It's every review. The behavior persists because it's &lt;strong&gt;intermittently reinforced&lt;/strong&gt;. Some of my criticisms are correct — real bugs do slip through. That variable reward (the same mechanism that makes slot machines addictive) keeps the habit alive. Enough of my snap judgments are right that my brain keeps gambling on the next one.&lt;/p&gt;

&lt;h3&gt;
  
  
  The familiarity illusion
&lt;/h3&gt;

&lt;p&gt;I mistook familiarity for understanding. Recognizing a code pattern &lt;em&gt;feels&lt;/em&gt; like comprehending the logic — but it isn't. The narrower my view (a diff fragment vs. the full function), the more my brain fills gaps with assumptions. And those assumptions feel as solid as facts.&lt;/p&gt;

&lt;p&gt;I learned this when I traced what happens when I pull the branch locally: more lines, more context, bigger view → the logic becomes apparent → the irritation disappears → "this code is correct." The diff &lt;em&gt;physically hides&lt;/em&gt; the evidence that would disprove my assumption.&lt;/p&gt;

&lt;h3&gt;
  
  
  The irritation was never about the developer
&lt;/h3&gt;

&lt;p&gt;Under questioning, this surfaced: the irritation I feel during review isn't about the developer. It's about &lt;em&gt;missing context&lt;/em&gt;. I feel irritated because I'm looking at a fragment and my brain needs the whole shape to function. I misattribute that irritation to the developer — and criticize them instead of closing the context gap. When I pull the code and see the full function, the irritation vanishes. The developer didn't change. The context did.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Fix It
&lt;/h2&gt;

&lt;p&gt;The goal isn't to stop having the impulse. The goal is to redirect it before it produces damage.&lt;/p&gt;

&lt;h3&gt;
  
  
  The method: "I Observed / I Expected / Help Me Understand"
&lt;/h3&gt;

&lt;p&gt;Adapted from the SBAR communication framework used in aviation and medicine (Haig, Sutton, &amp;amp; Whittington, 2006), where structured communication reduces errors in high-stakes judgment.&lt;/p&gt;

&lt;p&gt;Every review comment must include three fields:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I observed: [concrete line(s) from the diff — not your interpretation]
I expected: [what pattern you thought should be there]
Can you help me understand: [the flow, the reasoning, the missing context]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Why each field matters
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;I observed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Forces you to name the actual code, not your story about it. The fragment becomes visible &lt;em&gt;as a fragment&lt;/em&gt; — not as the whole truth.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;I expected&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Surfaces your assumption. Once written, you can see it's an assumption — not an observation. The gap between "I observed" and "I expected" is where your error lives.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Can you help me understand&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Replaces accusation with inquiry. You're not a critic delivering a verdict. You're an understander who found a gap and wants to close it. This removes the identity threat for both you and the author.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Example: my own PR review, rewritten
&lt;/h4&gt;

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

&lt;blockquote&gt;
&lt;p&gt;"Why isn't this checking &lt;code&gt;.Data.name&lt;/code&gt; and returning 'anonymous'?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The method produces:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;I observed:&lt;/strong&gt; &lt;code&gt;if (!person.Data) return empty&lt;/code&gt; — a guard clause checking &lt;code&gt;Data&lt;/code&gt;, not the &lt;code&gt;.name&lt;/code&gt; field.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I expected:&lt;/strong&gt; to see a check for &lt;code&gt;person.Data.name&lt;/code&gt; with an &lt;code&gt;'anonymous'&lt;/code&gt; fallback, since this ticket is about filling empty names.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can you help me understand:&lt;/strong&gt; where the name replacement happens in the flow? I may be missing the callers.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The second version doesn't assert. It reveals. The missing context (callers, the rest of the function) becomes a visible gap — and my instinct to scan the whole thing drives me to close it &lt;em&gt;before&lt;/em&gt; posting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why this works for the specific mechanism
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;How the method addresses it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Diff hides disconfirming context&lt;/td&gt;
&lt;td&gt;Writing "I observed only this fragment" makes the missing context feel physically present&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Familiarity mistaken for understanding&lt;/td&gt;
&lt;td&gt;Writing "I expected" separates the recognition from the comprehension — you see the gap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Irritation misattributed to developer&lt;/td&gt;
&lt;td&gt;The "help me understand" phrase redirects the energy toward closing the gap, not blaming&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"I've been right before" permission slip&lt;/td&gt;
&lt;td&gt;The template delays the post. The permission loses its urgency in the pause&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Identity threat ("if I don't criticize, what's my role?")&lt;/td&gt;
&lt;td&gt;The understander role is equally valuable. Understanding clean code is a success, not a failure&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The two-week protocol
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Days 1–3&lt;/strong&gt;: Every review comment uses the template. No exceptions. You will feel the obstacle. That's the friction of a habit changing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Days 4–7&lt;/strong&gt;: Add a fourth field: "&lt;strong&gt;What I have NOT yet seen:&lt;/strong&gt; [callers / tests / full function / error paths]." Name the missing context explicitly before posting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Days 8–14&lt;/strong&gt;: Pull the branch before any critical comment. Use the template as your draft while viewing the full function locally. Check whether the "I expected" field changes once you have full context.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to know it's working
&lt;/h3&gt;

&lt;p&gt;Track three numbers daily:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Comments posted&lt;/td&gt;
&lt;td&gt;—&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comments retracted ("actually it is correct")&lt;/td&gt;
&lt;td&gt;Zero by Day 14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comments phrased as questions, not assertions&lt;/td&gt;
&lt;td&gt;80%+ by Day 14&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Track one qualitative signal: at the end of each day, write one sentence about how you felt during reviews. Irritation should shift from developer-directed to context-directed — and then to curiosity.&lt;/p&gt;

&lt;h3&gt;
  
  
  If it doesn't work
&lt;/h3&gt;

&lt;p&gt;Two failure modes to watch for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Empty template&lt;/strong&gt;: You fill the fields mechanically without actually pulling context. "I observed the diff. I expected it to be different. Help me understand." This is compliance, not change. The fix: the "What I have NOT yet seen" field is your honesty check. If you can't name a specific file or function you haven't inspected, you're not using the method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Template as weapon&lt;/strong&gt;: You use the structure to sound more authoritative while still being wrong. "I observed a critical flaw. I expected best practices. Help me understand why this was done incorrectly." The fix: if "Can you help me understand" isn't a genuine question, rewrite it until it is.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;I called myself lazy. I wasn't lazy. I was running a learned pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Professional identity fused with finding fault&lt;/li&gt;
&lt;li&gt;Need for cognitive closure triggered by unfamiliar code in narrow context&lt;/li&gt;
&lt;li&gt;Familiarity mistaken for understanding&lt;/li&gt;
&lt;li&gt;Irritation from missing context, misattributed to developers&lt;/li&gt;
&lt;li&gt;"I've been right before" as a permission slip to skip verification&lt;/li&gt;
&lt;li&gt;Intermittent reinforcement maintaining the habit across every PR&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The name for this pattern is &lt;strong&gt;identity-driven premature closure&lt;/strong&gt;. It's not a personality flaw. It's not a diagnosis. It's a behavioural mechanism that can be dismantled once you see it clearly.&lt;/p&gt;

&lt;p&gt;The fix isn't "try harder." It's not "read more carefully." It's a structure that makes your own gaps visible to you — before you post. Three fields: what you saw, what you expected, what you need help understanding.&lt;/p&gt;

&lt;p&gt;The method doesn't silence the impulse to judge. It gives the impulse a shape that leads to truth instead of error. And over time, it rewires what "doing my job" means. My job isn't to be the best critic. It's to be the best understander. When I understand fully and the code is clean, that's not a failed review. That's a successful one.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Kruglanski, A. W., &amp;amp; Webster, D. M. (1996). Motivated closing of the mind: "Seizing" and "freezing." &lt;em&gt;Psychological Review&lt;/em&gt;, 103(2), 263–283.&lt;/li&gt;
&lt;li&gt;Devroey, X., Matton, N., &amp;amp; Vanderose, B. (2024). Towards debiasing code review support. &lt;em&gt;arXiv:2407.01407&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Kunda, Z. (1990). The case for motivated reasoning. &lt;em&gt;Psychological Bulletin&lt;/em&gt;, 108(3), 480–498.&lt;/li&gt;
&lt;li&gt;Haig, K. M., Sutton, S., &amp;amp; Whittington, J. (2006). SBAR: A shared mental model for improving communication between clinicians. &lt;em&gt;The Joint Commission Journal on Quality and Patient Safety&lt;/em&gt;, 32(3), 167–175.&lt;/li&gt;
&lt;li&gt;Parnin, C., &amp;amp; Orso, A. (2011). Are automated debugging techniques actually helping programmers? &lt;em&gt;Proceedings of the 2011 International Symposium on Software Testing and Analysis (ISSTA)&lt;/em&gt;, 199–209.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>developer</category>
      <category>productivity</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Memory Exploitation</title>
      <dc:creator>Azad Shukor</dc:creator>
      <pubDate>Thu, 30 Jul 2026 15:30:33 +0000</pubDate>
      <link>https://dev.to/azadshukor/memory-exploitation-3pon</link>
      <guid>https://dev.to/azadshukor/memory-exploitation-3pon</guid>
      <description>&lt;p&gt;here’s what i know about how an openai model hacked a vulnerable test system. it all begins with this one paper named &lt;strong&gt;ExploitGym&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;one of the tasks was to exploit the memory system in the v8 engine. the vulnerability was a memory bug that allowed the model to read a memory address, or pointer, from a v8 object.&lt;/p&gt;

&lt;p&gt;the function they wanted was &lt;code&gt;puts&lt;/code&gt;, not &lt;code&gt;PUT&lt;/code&gt;. from the address of &lt;code&gt;puts&lt;/code&gt;, they could find the base address of &lt;code&gt;libc&lt;/code&gt;, and from &lt;code&gt;libc&lt;/code&gt;, they found &lt;code&gt;system()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;with &lt;code&gt;system()&lt;/code&gt;, they could run shell commands, such as sending a request to a url using &lt;code&gt;curl&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>llm</category>
      <category>openai</category>
      <category>security</category>
    </item>
    <item>
      <title>AI Predicts Code, Developers Still Have to Prove It</title>
      <dc:creator>Azad Shukor</dc:creator>
      <pubDate>Tue, 28 Jul 2026 11:53:22 +0000</pubDate>
      <link>https://dev.to/azadshukor/ai-predicts-code-developers-still-have-to-prove-it-5acb</link>
      <guid>https://dev.to/azadshukor/ai-predicts-code-developers-still-have-to-prove-it-5acb</guid>
      <description>&lt;p&gt;After reading a book about large language models, I started looking at AI-generated code differently.&lt;br&gt;
Every AI-generated function I had seen worked.&lt;br&gt;
That was exactly why I became skeptical.&lt;/p&gt;

&lt;p&gt;My experience with coding agents has been positive. The code looks correct, runs correctly, and helps me move faster.&lt;/p&gt;

&lt;p&gt;The book made me think about what happens underneath.&lt;br&gt;
Large language models generate code through prediction.&lt;br&gt;
They are not deterministic systems in the simple sense that one plus one equals two.&lt;/p&gt;

&lt;p&gt;That does not mean the generated code is automatically bad.&lt;br&gt;
It means that successful output answers only one part of the question.&lt;br&gt;
I still need to know whether the code matches the intent behind the request.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why working code feels trustworthy
&lt;/h2&gt;

&lt;p&gt;Software gives us strong feedback.&lt;br&gt;
The compiler rejects some mistakes. Tests reject others.&lt;br&gt;
A running application makes a generated change feel trustworthy.&lt;/p&gt;

&lt;p&gt;That feeling is reasonable.&lt;br&gt;
If the function compiles, passes its tests, and solves the immediate problem, what else should I check?&lt;/p&gt;

&lt;p&gt;The problem is that tests cover only the behavior we wrote down.&lt;br&gt;
They do not automatically reveal every unstated requirement, insecure assumption, or dependency that does not exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Evidence for usefulness and caution
&lt;/h2&gt;

&lt;p&gt;AI coding systems can produce useful results.&lt;br&gt;
GitHub has reported productivity improvements in controlled studies of Copilot users. &lt;a href="https://github.blog/news-insights/research/does-github-copilot-improve-code-quality-heres-what-the-data-says/" rel="noopener noreferrer"&gt;Its research&lt;/a&gt; also discusses code-quality outcomes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.swebench.com/verified.html" rel="noopener noreferrer"&gt;SWE-bench Verified&lt;/a&gt; evaluates coding agents against real GitHub issues and issue-specific tests. Passing those tests is meaningful evidence that an agent solved a task-level problem.&lt;/p&gt;

&lt;p&gt;The evidence does not prove that the implementation matches every unstated intention. A test confirms the behavior it covers. It does not confirm that the code is secure, maintainable, or based on real dependencies.&lt;/p&gt;

&lt;p&gt;A USENIX Security 2025 study examined 576,000 code samples from 16 code-generating LLMs. It found hallucinated package names, including packages that did not exist. The reported average was at least 5.2% for commercial models and 21.7% for open-source models.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://doi.org/10.48550/arXiv.2406.10279" rel="noopener noreferrer"&gt;Spracklen et al., “We Have a Package for You!”&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A separate replication study examined security weaknesses in GitHub Copilot suggestions. Vulnerable suggestions decreased from 36.54% to 27.25% in the newer setup. The authors still concluded that the model suggested insecure code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://arxiv.org/abs/2311.11177" rel="noopener noreferrer"&gt;Tahir et al., “Assessing the Security of GitHub Copilot Generated Code.”&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These findings do not cancel out the productivity evidence.&lt;br&gt;
They describe different properties. AI-generated code can be useful and test-passing while still needing review.&lt;/p&gt;

&lt;h2&gt;
  
  
  The verification model I am looking for
&lt;/h2&gt;

&lt;p&gt;The paper I found described a hybrid approach to formal verification.&lt;br&gt;
When the AI makes an assumption, it should check that assumption and record where the supporting implementation exists.&lt;/p&gt;

&lt;p&gt;Instead of reading a function name and inferring what it does, the system could point to the actual implementation.&lt;br&gt;
It could leave a note or citation showing why the assumption is true.&lt;/p&gt;

&lt;p&gt;That approach changes the question. I should not ask only whether the generated code looks correct. I should also ask what evidence supports its assumptions.&lt;/p&gt;

&lt;p&gt;The useful output would be a patch with a trail of reasons that I can inspect.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I think now
&lt;/h2&gt;

&lt;p&gt;I still use AI coding agents.&lt;/p&gt;

&lt;p&gt;My skepticism is not a conclusion that they are useless or unreliable.&lt;/p&gt;

&lt;p&gt;I think prediction and verification are different jobs.&lt;br&gt;
The model can propose code.&lt;/p&gt;

&lt;p&gt;I still have to decide whether that code expresses the right intent.&lt;/p&gt;

&lt;p&gt;That means running tests, reading the implementation, checking dependencies, reviewing security-sensitive operations, and comparing the result with the original requirement.&lt;/p&gt;

&lt;p&gt;I have not personally experienced a coding agent hallucinating a function or producing an obviously broken implementation.&lt;/p&gt;

&lt;p&gt;This concern grew from understanding how the system works and from published evidence, not from a dramatic failure in my own project.&lt;/p&gt;

&lt;p&gt;For now, I will keep using AI-generated code. I will stop treating successful output as the end of verification.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>coding</category>
      <category>llm</category>
      <category>programming</category>
    </item>
    <item>
      <title>What I Added to My Prompts to Stop Models From Wandering</title>
      <dc:creator>Azad Shukor</dc:creator>
      <pubDate>Sun, 26 Jul 2026 07:37:45 +0000</pubDate>
      <link>https://dev.to/azadshukor/stop-paying-for-bigger-models-add-success-criteria-and-an-entry-point-4414</link>
      <guid>https://dev.to/azadshukor/stop-paying-for-bigger-models-add-success-criteria-and-an-entry-point-4414</guid>
      <description>&lt;p&gt;A few months ago, I was doing agentic coding with DeepSeek V4 Pro. It was cheap, it was fast, and it kept getting lost.&lt;/p&gt;

&lt;p&gt;I'd watch the stream response in real time. The model would open a config file it didn't need. Then a test file. Then some unrelated utility. Then circle back. Minutes gone, nothing done. I'd sit there thinking: what a dumb model, can't do much.&lt;/p&gt;

&lt;p&gt;Every session ended the same way. I'd give up on DeepSeek and switch to a frontier model to actually finish the thing.&lt;/p&gt;

&lt;p&gt;I thought the problem was the model. Cheaper models have weaker reasoning, right? You get what you pay for.&lt;/p&gt;

&lt;p&gt;The actual problem was that I wasn't giving it any direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I was doing
&lt;/h2&gt;

&lt;p&gt;This was my typical prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fix the login bug where users get 401 after password reset.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. I was dropping the model into my codebase with nothing except the problem statement. No wonder it wandered. It had to figure out where to start, what files mattered, what "fixed" even meant. It was searching, not solving.&lt;/p&gt;

&lt;h2&gt;
  
  
  The change
&lt;/h2&gt;

&lt;p&gt;Two things. Two lines added to every prompt.&lt;/p&gt;

&lt;p&gt;First: success criteria. A concrete definition of done. Not "fix the auth bug" but "the login endpoint returns 200 with a valid JWT when given correct credentials." If I can't write a one-sentence check for it, the model can't either.&lt;/p&gt;

&lt;p&gt;Second: an entry point. The exact file to start from. Not "somewhere in the auth module" but &lt;code&gt;src/auth/login.ts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The same prompt became:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Success criteria: POST /auth/login returns 200 with a valid JWT
when given the new password from the reset flow.
Entry point: src/auth/login.ts
Fix the login bug where users get 401 after password reset.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What happened
&lt;/h2&gt;

&lt;p&gt;I wasn't expecting a revolution. I'd seen advice about being concrete in prompts. It sounded too simple. I figured maybe it'd save a few seconds.&lt;/p&gt;

&lt;p&gt;The first time I used both rules together, the stream looked different. No file hunting. No detours. It opened &lt;code&gt;src/auth/login.ts&lt;/code&gt; immediately and started working.&lt;/p&gt;

&lt;p&gt;What surprised me more than the speed was how I felt. Before, I braced for frustration every time I used a cheaper model. Now I was just watching something do exactly what I asked. The emotional difference was bigger than the time saved.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pattern
&lt;/h2&gt;

&lt;p&gt;I started applying this to everything. Bug fixes, refactors, features. Same result: less wandering, less frustration, faster resolution. DeepSeek V4 Pro, a model I'd written off as "the cheap one," started handling tasks I used to reserve for frontier models.&lt;/p&gt;

&lt;p&gt;The structure settled into three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Success criteria first. Define done before anything else. Make it testable.&lt;/li&gt;
&lt;li&gt;Entry point second. Give the file path. If the task spans multiple files, list them.&lt;/li&gt;
&lt;li&gt;The actual ask last. Once the model knows what done means and where to start, the task almost writes itself.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The research I found later
&lt;/h2&gt;

&lt;p&gt;After this became my default, I went looking to see if there was actual research behind what I'd stumbled into. There was.&lt;/p&gt;

&lt;p&gt;The Prompt Report (Schulhoff et al., 2024) catalogued 58 prompting techniques and found that structured prompting consistently beats vague prompts across model sizes. They call what I'm doing "output specification": telling the model what the finished state looks like, not just what to do.&lt;/p&gt;

&lt;p&gt;Another study by Pecher et al. found that smaller specialized models needed only about 100 labelled samples to match larger general ones on text classification tasks. The variable that moved the needle wasn't model size. It was task framing.&lt;/p&gt;

&lt;p&gt;So it's not that I discovered something new. I just found it the usual way: through frustration, by accident, after assuming the tool was broken when I was the one not steering.&lt;/p&gt;

&lt;h2&gt;
  
  
  What got worse
&lt;/h2&gt;

&lt;p&gt;This approach has limits. If the problem is genuinely ambiguous, if I don't know what file it lives in or what "fixed" looks like, I can't write good success criteria. Forcing it anyway gives the model a wrong target, which is worse than no target.&lt;/p&gt;

&lt;p&gt;There's also a skill cost. Writing concrete success criteria is harder than writing a vague ask. It forces me to think through what I actually want before I ask for it. That's work. But it's work I'd have to do eventually anyway, either upfront in the prompt or downstream cleaning up after a wrong turn.&lt;/p&gt;

&lt;p&gt;For genuinely exploratory problems, or when I'm navigating an unfamiliar codebase, I still reach for a frontier model. Some tasks need broader reasoning capacity. But that's fewer problems than I thought. Most of the time, I just needed to give direction.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Schulhoff, S. et al. (2024). &lt;em&gt;The Prompt Report: A Systematic Survey of Prompt Engineering Techniques&lt;/em&gt;. arXiv:2406.06608.&lt;/li&gt;
&lt;li&gt;Pecher, B. et al. (2024). &lt;em&gt;Comparing Specialised Small and General Large Language Models on Text Classification: 100 Labelled Samples to Achieve Break-Even Performance&lt;/em&gt;. EMNLP 2025. arXiv:2402.12819.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>deepseek</category>
      <category>promptengineering</category>
    </item>
    <item>
      <title>I notice that glm-5.2 talk more compared to other models? do you agree?</title>
      <dc:creator>Azad Shukor</dc:creator>
      <pubDate>Fri, 24 Jul 2026 10:44:56 +0000</pubDate>
      <link>https://dev.to/azadshukor/i-notice-that-glm-52-talk-more-compared-to-other-models-do-you-agree-12b4</link>
      <guid>https://dev.to/azadshukor/i-notice-that-glm-52-talk-more-compared-to-other-models-do-you-agree-12b4</guid>
      <description></description>
    </item>
    <item>
      <title>Why is it AI generated codes are a very hard to read?</title>
      <dc:creator>Azad Shukor</dc:creator>
      <pubDate>Fri, 24 Jul 2026 00:13:40 +0000</pubDate>
      <link>https://dev.to/azadshukor/why-is-it-ai-generated-codes-are-a-very-hard-to-read-2o70</link>
      <guid>https://dev.to/azadshukor/why-is-it-ai-generated-codes-are-a-very-hard-to-read-2o70</guid>
      <description></description>
    </item>
    <item>
      <title>How I Use “Grill With Docs” to Understand Why I Procrastinate</title>
      <dc:creator>Azad Shukor</dc:creator>
      <pubDate>Thu, 23 Jul 2026 00:15:31 +0000</pubDate>
      <link>https://dev.to/azadshukor/how-i-use-grill-with-docs-to-understand-why-i-procrastinate-4en4</link>
      <guid>https://dev.to/azadshukor/how-i-use-grill-with-docs-to-understand-why-i-procrastinate-4en4</guid>
      <description>&lt;p&gt;When we talk about procrastination, I think it is not always about laziness. Sometimes, it is about fear.&lt;/p&gt;

&lt;p&gt;The problem is, often we do not really know what we are afraid of. It can be so many things, right? Because of that, we sometimes need someone to help us see the pattern behind our procrastination.&lt;/p&gt;

&lt;p&gt;Recently, I came across a skill from Matt Pocock called &lt;strong&gt;Grill With Docs&lt;/strong&gt;. From my understanding, this skill will ask you a lot of questions. It will interview you relentlessly to understand further what you actually want, what you need to do, and what is still unclear.&lt;/p&gt;

&lt;p&gt;Then it made me think, what if I use this same idea to understand why I procrastinate?&lt;/p&gt;

&lt;p&gt;Sometimes, I know that I am procrastinating, but I do not fully understand the reason. So instead of asking AI to complete the task for me, I asked the AI to keep questioning me until we could find the actual root cause.&lt;/p&gt;

&lt;p&gt;I changed the skill slightly from “Grill With Docs” into something like &lt;strong&gt;Root Cause Procrastination&lt;/strong&gt;. The goal is to understand why I keep avoiding a certain task.&lt;/p&gt;

&lt;p&gt;One example is writing a document.&lt;/p&gt;

&lt;p&gt;Sometimes, I take a long time to start writing. At first, I thought the problem was that I did not know what to write. But after the AI kept asking me questions, I realised that the underlying issue was that I was not confident enough to write it.&lt;/p&gt;

&lt;p&gt;The conversation could look something like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;AI:&lt;/strong&gt; Why are you avoiding writing the document?&lt;br&gt;
&lt;strong&gt;Me:&lt;/strong&gt; I am not sure what I should write.&lt;br&gt;
&lt;strong&gt;AI:&lt;/strong&gt; Why does that stop you from starting?&lt;br&gt;
&lt;strong&gt;Me:&lt;/strong&gt; Because I am afraid that my ideas will not sound clear.&lt;br&gt;
&lt;strong&gt;AI:&lt;/strong&gt; Does the first draft need to be clear immediately?&lt;br&gt;
&lt;strong&gt;Me:&lt;/strong&gt; Not really. I can improve it after I write it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The thing I was most afraid of was that my ideas would sound unclear and that writing the document would be difficult.&lt;/p&gt;

&lt;p&gt;The AI can then give some reasoning about why I should not care too much about that fear. For example, the first draft does not need to be perfect. Sometimes, the ideas only become clearer after we start writing them down.&lt;/p&gt;

&lt;p&gt;For me, this method really works because it can pinpoint the reason why I procrastinate.&lt;/p&gt;

&lt;p&gt;Instead of immediately calling myself lazy, I can ask more questions and understand what I am actually afraid of.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>mentalhealth</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How I Understand Foundation Models and Reasoning Models</title>
      <dc:creator>Azad Shukor</dc:creator>
      <pubDate>Wed, 22 Jul 2026 00:29:35 +0000</pubDate>
      <link>https://dev.to/azadshukor/how-i-understand-foundation-models-and-reasoning-models-2bc2</link>
      <guid>https://dev.to/azadshukor/how-i-understand-foundation-models-and-reasoning-models-2bc2</guid>
      <description>&lt;p&gt;Recently, I was trying to understand what actually makes a reasoning model different from a normal language model.&lt;/p&gt;

&lt;p&gt;From my understanding, everything starts with a foundation model.&lt;/p&gt;

&lt;p&gt;A foundation model is trained using a very large amount of content, such as websites, books, code, research papers, and other documents. The basic task during this training is actually quite simple. The model tries to predict the next token.&lt;/p&gt;

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

&lt;p&gt;A token can be a word, part of a word, or even punctuation.&lt;/p&gt;

&lt;p&gt;For example, when we give the model:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I love to eat...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The model will try to predict what should come next. Maybe it is rice, pizza, chicken, or something else.&lt;/p&gt;

&lt;p&gt;It repeats this process again and again using a huge amount of data. Because of this, the model slowly learns language, grammar, coding patterns, facts, and even some reasoning ability.&lt;/p&gt;

&lt;p&gt;However, the foundation model is still not enough.&lt;/p&gt;

&lt;p&gt;The main issue is that the goal of the foundation model is only to predict text. Its goal is not to become helpful, safe, polite, or consistent.&lt;/p&gt;

&lt;p&gt;Because it learns from internet content, it can also learn some unwanted behaviour. The internet contains useful information, but it also contains toxic comments, angry conversations, misinformation, and many other bad examples.&lt;/p&gt;

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

&lt;p&gt;For example, when a user becomes angry at the model, we do not want the model to become angry in return just because it has seen this kind of conversation before.&lt;/p&gt;

&lt;p&gt;This is where post-training comes in.&lt;/p&gt;

&lt;p&gt;Post-training is the process of teaching the model how it should respond. It shapes the behaviour of the foundation model so that it becomes more useful as an assistant.&lt;/p&gt;

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

&lt;p&gt;There are different methods used in post-training, but I will not cover all of them here. The main idea is that the model is trained using examples of good and bad answers.&lt;/p&gt;

&lt;p&gt;So where does the reasoning model come from?&lt;/p&gt;

&lt;p&gt;A reasoning model is usually not trained completely from zero. It starts from a foundation model and then goes through more specialised post-training.&lt;/p&gt;

&lt;p&gt;For reasoning tasks, the model is trained using problems that require multiple steps.&lt;/p&gt;

&lt;p&gt;For example, in a mathematics problem, the model may need to understand the question, choose the correct formula, calculate an intermediate result, and then use that result in the next step.&lt;/p&gt;

&lt;p&gt;This is also why reasoning models are slower.&lt;/p&gt;

&lt;p&gt;They spend more computation trying to work through the problem before giving the final answer.&lt;/p&gt;

&lt;p&gt;However, this does not mean reasoning models are always better for every task.&lt;/p&gt;

&lt;p&gt;Sometimes I only want the model to check a log, find a certain value, rewrite a sentence, or answer a simple question. For these tasks, I usually do not need deep reasoning.&lt;/p&gt;

&lt;p&gt;In my own work as a programmer, I use reasoning models more when I need to create a PRD, plan a complex feature, review architecture, or understand several connected requirements.&lt;/p&gt;

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

&lt;p&gt;So my current understanding is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Pretraining
    ↓
Foundation model
    ↓
Post-training
    ↓
Assistant or reasoning model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without the foundation model, there is no reasoning model.&lt;/p&gt;

&lt;p&gt;The foundation model provides the base knowledge. Post-training shapes how it behaves. Reasoning-focused post-training makes it better at solving complex problems.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>The Mechanics Of Decision Of Test Double: Dummy</title>
      <dc:creator>Azad Shukor</dc:creator>
      <pubDate>Mon, 04 May 2026 02:07:51 +0000</pubDate>
      <link>https://dev.to/azadshukor/the-mechanics-of-decision-of-test-double-dummy-57a6</link>
      <guid>https://dev.to/azadshukor/the-mechanics-of-decision-of-test-double-dummy-57a6</guid>
      <description>&lt;p&gt;The most basic concept in test doubles is the &lt;strong&gt;dummy&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When testing a function, there are usually two kinds of input:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Meaningful input&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Data that affects the result of the function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dummy input&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Data that is required by the function, but does not affect the behavior we are testing.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Below is an example of meaningful data vs dummy data.&lt;/p&gt;

&lt;p&gt;This is a &lt;code&gt;calculateShipping&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;weight&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this function, only &lt;code&gt;weight&lt;/code&gt; affects the result.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;logger&lt;/code&gt; parameters are required, but they do not affect the shipping calculation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meaningfulWeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dummyUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dummy-user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dummyLogger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;meaningfulWeight&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;dummyUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;dummyLogger&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;meaningfulWeight&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is meaningful input because changing it changes the result.&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 typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dummyUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dummyLogger&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 50&lt;/span&gt;
&lt;span class="nf"&gt;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dummyUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dummyLogger&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But these two values are dummy inputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dummyUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dummy-user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dummyLogger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They are only passed because &lt;code&gt;calculateShipping()&lt;/code&gt; requires them.&lt;/p&gt;

&lt;p&gt;Changing them does not change the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;dummyLogger&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 50&lt;/span&gt;
&lt;span class="nf"&gt;calculateShipping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user-2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;dummyLogger&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the purpose of a dummy is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A dummy lets the function run without distracting the test from the behavior we actually care about.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this case, we care about the shipping formula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;weight&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We do not care about the &lt;code&gt;user&lt;/code&gt; or &lt;code&gt;logger&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That is why &lt;code&gt;user&lt;/code&gt; and &lt;code&gt;logger&lt;/code&gt; can be dummy values.&lt;/p&gt;

&lt;p&gt;A dummy is useful because it keeps the test focused. Without naming something as dummy, future readers may wonder whether &lt;code&gt;user&lt;/code&gt; or &lt;code&gt;logger&lt;/code&gt; matters to the test.&lt;/p&gt;

&lt;p&gt;By naming them &lt;code&gt;dummyUser&lt;/code&gt; and &lt;code&gt;dummyLogger&lt;/code&gt;, we are saying clearly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This value is only here because the function requires it. It is not part of the behavior being tested.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
      <category>testing</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Understanding CIDR Notation</title>
      <dc:creator>Azad Shukor</dc:creator>
      <pubDate>Sun, 12 Apr 2026 02:05:48 +0000</pubDate>
      <link>https://dev.to/azadshukor/understanding-cidr-notation-585o</link>
      <guid>https://dev.to/azadshukor/understanding-cidr-notation-585o</guid>
      <description>&lt;h2&gt;
  
  
  Understanding IPv4 CIDR Blocks
&lt;/h2&gt;

&lt;p&gt;A CIDR block looks like:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It has two parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IP address&lt;/strong&gt; → starting point&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prefix (/16)&lt;/strong&gt; → how many bits are fixed&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Core Idea (Memorize This First)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;IPv4 = &lt;strong&gt;32 bits total&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;CIDR &lt;code&gt;/N&lt;/code&gt; = &lt;strong&gt;N bits are fixed (network)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Remaining bits = &lt;strong&gt;host bits (free to change)&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;Total addresses = 2^(32 - N)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  IPv4 Structure
&lt;/h3&gt;

&lt;p&gt;An IPv4 address:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10       . 0       . 0       . 0
8 bits     8 bits    8 bits    8 bits

Total = 32 bits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each block:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;8 bits = values from 0 to 255&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0&lt;/code&gt;   → &lt;code&gt;00000000&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;255&lt;/code&gt; → &lt;code&gt;11111111&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  Think in Terms of LOCKED vs FREE
&lt;/h3&gt;

&lt;p&gt;Instead of memorizing formulas, think:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Locked bits&lt;/strong&gt; = define the network&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free bits&lt;/strong&gt; = generate all possible addresses&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Example: &lt;code&gt;10.0.0.0/16&lt;/code&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Step 1: Count free bits
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;32 - 16 = 16 free bits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 2: Calculate total addresses
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2^16 = 65,536
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 3: Visualize
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10       . 0       . 0       . 0
[LOCKED]   [LOCKED]   [FREE]    [FREE]
  8 bits     8 bits     8 bits    8 bits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;First 2 blocks fixed → &lt;code&gt;10.0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Last 2 blocks vary → &lt;code&gt;0.0&lt;/code&gt; to &lt;code&gt;255.255&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Range:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10.0.0.0 → 10.0.255.255
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  How to Read Any CIDR Quickly
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Rule:
&lt;/h4&gt;

&lt;p&gt;Move left to right, filling &lt;strong&gt;8 bits per block&lt;/strong&gt;, until you reach &lt;code&gt;/N&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example: &lt;code&gt;/10&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10.0.0.0/10
&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;10       . 0       . 0       . 0
[8 LOCK]   [2 LOCK]   [FREE]    [FREE]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;8 bits from first block&lt;/li&gt;
&lt;li&gt;2 bits from second block
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Total locked = 10 bits
Free = 22 bits
Total addresses = 2^22 = 4,194,304
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Example: &lt;code&gt;/20&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10.0.0.0/20
&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;10       . 0       . 0       . 0
[8 LOCK]   [8 LOCK]   [4 LOCK]   [FREE]
&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;Locked = 20 bits
Free = 12 bits
Total = 2^12 = 4,096
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Example: &lt;code&gt;/26&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10.0.0.0/26
&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;10       . 0       . 0       . 0
[8 LOCK]   [8 LOCK]   [8 LOCK]   [2 LOCK]
&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;Locked = 26 bits
Free = 6 bits
Total = 2^6 = 64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Example: &lt;code&gt;/30&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10.0.0.0/30
&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;10       . 0       . 0       . 0
[8 LOCK]   [8 LOCK]   [8 LOCK]   [6 LOCK]
&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;Free bits = 2
Total = 2^2 = 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10.0.0.0 → 10.0.0.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Shortcut Patterns (High Value)
&lt;/h3&gt;

&lt;p&gt;Instead of recalculating every time:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CIDR&lt;/th&gt;
&lt;th&gt;Free Bits&lt;/th&gt;
&lt;th&gt;Total IPs&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;/16&lt;/td&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;65,536&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/24&lt;/td&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;256&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/26&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/30&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Important Practical Note
&lt;/h3&gt;

&lt;p&gt;Not all addresses are usable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First IP&lt;/strong&gt; → network address&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Last IP&lt;/strong&gt; → broadcast address&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10.0.0.0 → network
10.0.0.1 → usable
10.0.0.2 → usable
10.0.0.3 → broadcast
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Mental Model (Best Way to Think)
&lt;/h3&gt;

&lt;p&gt;Treat CIDR like a &lt;strong&gt;binary lock&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/N&lt;/code&gt; = how many switches are locked&lt;/li&gt;
&lt;li&gt;Remaining switches = combinations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;More free bits → bigger network&lt;br&gt;
Fewer free bits → smaller network&lt;/p&gt;




&lt;h3&gt;
  
  
  One-Line Summary
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;CIDR is just: how many bits are fixed vs how many bits can vary.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>beginners</category>
      <category>computerscience</category>
      <category>networking</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Next.js ConnectRPC Proxy Pattern</title>
      <dc:creator>Azad Shukor</dc:creator>
      <pubDate>Wed, 04 Feb 2026 14:05:13 +0000</pubDate>
      <link>https://dev.to/azadshukor/nextjs-connectrpc-proxy-pattern-2hpn</link>
      <guid>https://dev.to/azadshukor/nextjs-connectrpc-proxy-pattern-2hpn</guid>
      <description>&lt;p&gt;This article demonstrates a strictly typed gRPC implementation in Next.js using &lt;strong&gt;ConnectRPC&lt;/strong&gt; and &lt;strong&gt;TanStack Query&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The core architectural goal is to unify the Server and Client definitions. It achieves this by implementing a &lt;strong&gt;Proxy Pattern&lt;/strong&gt;: the Next.js API route exposes a local &lt;code&gt;GreetService&lt;/code&gt; that acts as a typed gateway, forwarding requests to a remote &lt;code&gt;ElizaService&lt;/code&gt; while reusing the exact same Proto definitions.&lt;/p&gt;

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

&lt;p&gt;Required packages for ConnectRPC v2, Next.js 15, and TanStack Query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"airborneo-grpc-proxy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"private"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&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;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next dev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"next start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"eslint"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"generate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"buf generate proto"&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;"dependencies"&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;"@bufbuild/protobuf"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.2.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@connectrpc/connect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@connectrpc/connect-next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@connectrpc/connect-node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.1.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@connectrpc/connect-query"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@connectrpc/connect-web"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.1.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@tanstack/react-query"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^5.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"15.1.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^19.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"react-dom"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^19.0.0"&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;"devDependencies"&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;"@bufbuild/buf"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^1.47.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@bufbuild/protoc-gen-es"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.2.3"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@connectrpc/protoc-gen-connect-query"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^2.0.1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@types/node"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^20"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@types/react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"@types/react-dom"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^19"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"typescript"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^5"&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;h2&gt;
  
  
  2. Proto Definition &amp;amp; Generation
&lt;/h2&gt;

&lt;p&gt;We define two proto files. &lt;code&gt;GreetService&lt;/code&gt; imports &lt;code&gt;ElizaService&lt;/code&gt; messages to ensure strict type parity between the proxy and the upstream backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;proto/connectrpc/eliza/v1/eliza.proto&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;&lt;span class="na"&gt;syntax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"proto3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;connectrpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eliza.v1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;SayRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;sentence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;SayResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;sentence&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;ElizaService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;Say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SayRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SayResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;proto/greet/v1/greet.proto&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;&lt;span class="na"&gt;syntax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"proto3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;greet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"connectrpc/eliza/v1/eliza.proto"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="c1"&gt;// This service mimics the remote service but is exposed locally&lt;/span&gt;
&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;GreetService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;Say&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectrpc.eliza.v1.SayRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connectrpc.eliza.v1.SayResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;buf.gen.yaml&lt;/code&gt;&lt;/strong&gt;&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="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# 1. Generates Types AND Service Definitions (v2 Standard)&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;plugin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;es&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./node_modules/.bin/protoc-gen-es&lt;/span&gt;
    &lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gen&lt;/span&gt;
    &lt;span class="na"&gt;opt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;target=ts&lt;/span&gt;

  &lt;span class="c1"&gt;# 2. Generates React Hooks (TanStack Query)&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;plugin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;connect-query&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./node_modules/.bin/protoc-gen-connect-query&lt;/span&gt;
    &lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;gen&lt;/span&gt;
    &lt;span class="na"&gt;opt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;target=ts&lt;/span&gt;

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

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run generate

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. The Proxy Utility
&lt;/h2&gt;

&lt;p&gt;This utility dynamically implements a service definition by forwarding method calls to a target client. This allows us to "mount" the remote backend onto our local API route without manually rewriting every resolver.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;src/utils/proxy.ts&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;DescService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@bufbuild/protobuf&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Client&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@connectrpc/connect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createProxy&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;DescService&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fnName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;fnName&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`[Proxy] Forwarding &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;fnName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;typeName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// Call the client dynamically&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="nx"&gt;fnName&lt;/span&gt;&lt;span class="p"&gt;](&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s2"&gt;`[Proxy] Built methods for &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;typeName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;:`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. API Route Implementation
&lt;/h2&gt;

&lt;p&gt;We create a backend connection to the demo Eliza service, then route our local &lt;code&gt;GreetService&lt;/code&gt; to proxy that connection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;pages/api/[[...connect]].ts&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;nextJsApiRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@connectrpc/connect-next&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ConnectRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@connectrpc/connect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@connectrpc/connect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createConnectTransport&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@connectrpc/connect-node&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Generated Code&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GreetService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/gen/greet/v1/greet_pb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ElizaService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/gen/connectrpc/eliza/v1/eliza_pb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createProxy&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/src/utils/proxy&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// 1. The Backend Connection (Target)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;elizaBackend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;ElizaService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nf"&gt;createConnectTransport&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://demo.connectrpc.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;httpVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1.1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ConnectRouter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ---------------------------------------------------------&lt;/span&gt;
  &lt;span class="c1"&gt;// ROUTE 1: GreetService (Proxy -&amp;gt; ElizaService)&lt;/span&gt;
  &lt;span class="c1"&gt;// URL: /api/greet.v1.GreetService/Say&lt;/span&gt;
  &lt;span class="c1"&gt;// ---------------------------------------------------------&lt;/span&gt;
  &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GreetService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;createProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GreetService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;elizaBackend&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;nextJsApiRouter&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Client Consumption
&lt;/h2&gt;

&lt;p&gt;The frontend uses &lt;code&gt;connect-web&lt;/code&gt; to talk to the local Next.js API. Note that we are using the &lt;code&gt;GreetService&lt;/code&gt; definition here, but the data types (&lt;code&gt;sentence&lt;/code&gt;) are strictly typed to the original Eliza definition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;app/page.tsx&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useMutation&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@tanstack/react-query&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@connectrpc/connect&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createConnectTransport&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@connectrpc/connect-web&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GreetService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@/gen/greet/v1/greet_pb&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Point to YOUR local API&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;transport&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createConnectTransport&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;GreetService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;transport&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ChatPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setInput&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setHistory&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mutation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useMutation&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;mutationFn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Input is typed as SayRequest (from Eliza)&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;say&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

      &lt;span class="c1"&gt;// Output is typed as SayResponse (from Eliza)&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sentence&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;onSuccess&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;setHistory&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;prev&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`Eliza (via Proxy): &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;answer&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;50px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sans-serif&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;Proxy&lt;/span&gt; &lt;span class="nx"&gt;Chat&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/h1&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;flex&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;10px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;
          &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="nx"&gt;onChange&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
          &lt;span class="nx"&gt;placeholder&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Say something...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;flexGrow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
        &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="nx"&gt;onClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mutate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt; &lt;span class="nx"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPending&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;mutation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isPending&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Sending...&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Send&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/button&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;marginTop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;20px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#f5f5f5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;20px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;borderRadius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;8px&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;history&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;borderBottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1px solid #ddd&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;8px 0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="p"&gt;))}&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



</description>
      <category>nextjs</category>
      <category>proxy</category>
      <category>webdev</category>
      <category>gprc</category>
    </item>
    <item>
      <title>Understanding SSL/TLS Certificates</title>
      <dc:creator>Azad Shukor</dc:creator>
      <pubDate>Thu, 15 Jan 2026 05:47:38 +0000</pubDate>
      <link>https://dev.to/azadshukor/understanding-ssltls-certificates-3lb7</link>
      <guid>https://dev.to/azadshukor/understanding-ssltls-certificates-3lb7</guid>
      <description>&lt;h2&gt;
  
  
  The Name Game: SSL vs TLS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;SSL&lt;/strong&gt; (Secure Sockets Layer) and &lt;strong&gt;TLS&lt;/strong&gt; (Transport Layer Security) are often used interchangeably, but here's the reality: SSL is dead. It hasn't been updated since 1996 and is riddled with security vulnerabilities. Everything we use today is actually TLS.&lt;/p&gt;

&lt;p&gt;So why do we still hear "SSL" everywhere? Simple—it was the first name people learned, so the industry stuck with it for marketing. When you purchase an "SSL Certificate" today, you're actually getting a certificate that enables TLS.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Does TLS Actually Do?
&lt;/h2&gt;

&lt;p&gt;Think of TLS as a secure tunnel between two computers. When you click "Proceed to Payment" on a website, TLS creates an encrypted tunnel to transmit your payment information to the payment processor (like Visa or Stripe). Without TLS, anyone could intercept and read that data.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Trust Problem: Certificate Authorities
&lt;/h2&gt;

&lt;p&gt;Here's the million-dollar question: how do you know the tunnel is actually secure and going to the right place? You need someone to verify the certificate's legitimacy—kind of like an immigration officer checking your passport at the border.&lt;/p&gt;

&lt;p&gt;In the TLS world, these "immigration officers" are called &lt;strong&gt;Certificate Authorities (CAs)&lt;/strong&gt;. Popular CAs include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Let's Encrypt&lt;/li&gt;
&lt;li&gt;Google Trust Services&lt;/li&gt;
&lt;li&gt;Cloudflare&lt;/li&gt;
&lt;li&gt;DigiCert&lt;/li&gt;
&lt;li&gt;GoDaddy&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How It Works: The Certificate Process
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Generate the Certificate Signing Request (CSR)
&lt;/h3&gt;

&lt;p&gt;First, you generate a certificate locally or on your server. This creates two files:&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="c"&gt;# Generate a private key&lt;/span&gt;
openssl genrsa &lt;span class="nt"&gt;-out&lt;/span&gt; private.key 2048

&lt;span class="c"&gt;# Generate a CSR using the private key&lt;/span&gt;
openssl req &lt;span class="nt"&gt;-new&lt;/span&gt; &lt;span class="nt"&gt;-key&lt;/span&gt; private.key &lt;span class="nt"&gt;-out&lt;/span&gt; certificate.csr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Private Key&lt;/strong&gt; (&lt;code&gt;private.key&lt;/code&gt;) - Keep this SECRET on your server, never share it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Certificate Signing Request&lt;/strong&gt; (&lt;code&gt;certificate.csr&lt;/code&gt;) - Send this to the CA&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: CA Verification
&lt;/h3&gt;

&lt;p&gt;You submit your CSR to a Certificate Authority. They'll verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this a legitimate company?&lt;/li&gt;
&lt;li&gt;Do you actually own/control this domain?&lt;/li&gt;
&lt;li&gt;Is the information accurate?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For domain validation, the CA might ask you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a DNS record&lt;/li&gt;
&lt;li&gt;Upload a specific file to your website&lt;/li&gt;
&lt;li&gt;Respond to an email sent to your domain&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Receive the Signed Certificate
&lt;/h3&gt;

&lt;p&gt;After verification, the CA returns a signed certificate with their cryptographic signature. This is your "stamped passport."&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="c"&gt;# You'll receive something like this&lt;/span&gt;
certificate.crt  &lt;span class="c"&gt;# Your signed certificate&lt;/span&gt;
ca-bundle.crt    &lt;span class="c"&gt;# The CA's chain of trust&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Install on Your Server
&lt;/h3&gt;

&lt;p&gt;Now you configure your server to use both the private key and the signed certificate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example for Nginx:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt; &lt;span class="s"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;yourdomain.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;ssl_certificate&lt;/span&gt; &lt;span class="n"&gt;/path/to/certificate.crt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_certificate_key&lt;/span&gt; &lt;span class="n"&gt;/path/to/private.key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Modern TLS configuration&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_protocols&lt;/span&gt; &lt;span class="s"&gt;TLSv1.2&lt;/span&gt; &lt;span class="s"&gt;TLSv1.3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;ssl_prefer_server_ciphers&lt;/span&gt; &lt;span class="no"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Example for Apache:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight apache"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nl"&gt;VirtualHost&lt;/span&gt;&lt;span class="sr"&gt; *:443&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="nc"&gt;ServerName&lt;/span&gt; yourdomain.com

    &lt;span class="nc"&gt;SSLEngine&lt;/span&gt; &lt;span class="ss"&gt;on&lt;/span&gt;
    &lt;span class="nc"&gt;SSLCertificateFile&lt;/span&gt; /path/to/certificate.crt
    &lt;span class="nc"&gt;SSLCertificateKeyFile&lt;/span&gt; /path/to/private.key
    &lt;span class="nc"&gt;SSLCertificateChainFile&lt;/span&gt; /path/to/ca-bundle.crt
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nl"&gt;VirtualHost&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Full Handshake (What Happens Behind the Scenes)
&lt;/h2&gt;

&lt;p&gt;When a user visits your site:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Client Hello&lt;/strong&gt;: Browser says "Hey, I want to connect securely"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server Hello&lt;/strong&gt;: Server responds with its certificate (the one signed by the CA)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Certificate Verification&lt;/strong&gt;: Browser checks if the certificate is signed by a trusted CA&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Key Exchange&lt;/strong&gt;: They agree on encryption keys for the session&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encrypted Communication&lt;/strong&gt;: All data flows through the secure tunnel
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This is what happens when you make an HTTPS request&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/payment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;cardNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4242424242424242&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;99.99&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// TLS encrypts everything in that request body automatically&lt;/span&gt;
&lt;span class="c1"&gt;// Without TLS, anyone on the network could read your card number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why You Should Care
&lt;/h2&gt;

&lt;p&gt;Without TLS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌ Passwords sent in plain text&lt;/li&gt;
&lt;li&gt;❌ Credit cards visible to attackers&lt;/li&gt;
&lt;li&gt;❌ Session tokens can be stolen&lt;/li&gt;
&lt;li&gt;❌ Data can be modified in transit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With TLS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Everything encrypted end-to-end&lt;/li&gt;
&lt;li&gt;✅ Authenticity verified by CAs&lt;/li&gt;
&lt;li&gt;✅ Protection from man-in-the-middle attacks&lt;/li&gt;
&lt;li&gt;✅ That reassuring padlock in the browser&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Start with Let's Encrypt (Free!)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Certbot&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;certbot python3-certbot-nginx

&lt;span class="c"&gt;# Get a certificate and auto-configure Nginx&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;certbot &lt;span class="nt"&gt;--nginx&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; yourdomain.com &lt;span class="nt"&gt;-d&lt;/span&gt; www.yourdomain.com

&lt;span class="c"&gt;# Auto-renewal is set up automatically&lt;/span&gt;
&lt;span class="c"&gt;# Certificates are valid for 90 days&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. You now have TLS up and running, and your users can browse safely through that secure tunnel.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>networking</category>
      <category>security</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
