<?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: Christian Mbah</title>
    <description>The latest articles on DEV Community by Christian Mbah (@chrismbah).</description>
    <link>https://dev.to/chrismbah</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%2F1282011%2F4c876717-9794-45c3-904b-987c79902515.png</url>
      <title>DEV Community: Christian Mbah</title>
      <link>https://dev.to/chrismbah</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chrismbah"/>
    <language>en</language>
    <item>
      <title>How to Use Webhooks in n8n: The Complete Beginner Guide</title>
      <dc:creator>Christian Mbah</dc:creator>
      <pubDate>Sat, 20 Jun 2026 08:32:25 +0000</pubDate>
      <link>https://dev.to/chrismbah/how-to-use-webhooks-in-n8n-the-complete-beginner-guide-3b32</link>
      <guid>https://dev.to/chrismbah/how-to-use-webhooks-in-n8n-the-complete-beginner-guide-3b32</guid>
      <description>&lt;p&gt;If you're building automations in n8n, the Webhook node is probably the single most useful trigger you'll touch. It's how the outside world talks to your workflow — a form submission, a Stripe payment, a CRM update, a custom app event. &lt;/p&gt;

&lt;p&gt;Once you understand webhooks properly, you stop thinking of n8n as "just a Zapier alternative" and start treating it as a real integration layer.&lt;/p&gt;

&lt;p&gt;Here's the practical version of everything you need to know.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a webhook actually is
&lt;/h2&gt;

&lt;p&gt;A webhook is just an HTTP endpoint. When something happens elsewhere (a form gets submitted, a payment succeeds), that external system sends an HTTP request to a URL you control. n8n's Webhook node gives you that URL and lets you build logic around whatever data shows up.&lt;/p&gt;

&lt;p&gt;No polling, no "check every 5 minutes" cron job pretending to be real-time. The event pushes data to you the instant it happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up your first webhook
&lt;/h2&gt;

&lt;p&gt;Drag a &lt;strong&gt;Webhook&lt;/strong&gt; node onto your canvas. You'll immediately see two URLs:&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%2Fegcz8jb7e9c7s0200wqh.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%2Fegcz8jb7e9c7s0200wqh.png" alt="n8n webhook details modal" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Test URL&lt;/strong&gt; — only works while you have the workflow open and are manually listening for a test event. Good for development.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production URL&lt;/strong&gt; — works once the workflow is activated, regardless of whether you're looking at it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Configure the basics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Method&lt;/strong&gt;: GET, POST, PUT, DELETE — whatever the sender uses. POST is most common for form/event data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Path&lt;/strong&gt;: customize this instead of using the random string n8n generates. &lt;code&gt;/onboarding-signup&lt;/code&gt; is a lot easier to debug than &lt;code&gt;/a3f9-xkq2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Respond&lt;/strong&gt;: decide whether n8n responds immediately ("Immediately") or after your workflow logic finishes ("When Last Node Finishes"). If the sender expects a fast response (most do, especially form tools with a 5-10s timeout), use "Immediately" and do your heavy logic afterward.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reading incoming data
&lt;/h2&gt;

&lt;p&gt;Whatever hits the webhook lands in &lt;code&gt;$json&lt;/code&gt; (or &lt;code&gt;{{ $json.body.fieldname }}&lt;/code&gt; if the payload is nested under &lt;code&gt;body&lt;/code&gt;, which it usually is for JSON POST requests).&lt;/p&gt;

&lt;p&gt;Quick way to check the shape of incoming data: send a test request and look at the &lt;strong&gt;Webhook&lt;/strong&gt; node's output panel. You'll see exactly how the payload is structured before you write a single expression.&lt;/p&gt;

&lt;p&gt;Common gotcha — if your sender posts as &lt;code&gt;application/x-www-form-urlencoded&lt;/code&gt; instead of &lt;code&gt;application/json&lt;/code&gt;, the data still lands in &lt;code&gt;$json&lt;/code&gt;, just structured differently. Always check the raw output rather than assuming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validating and securing the endpoint
&lt;/h2&gt;

&lt;p&gt;Anyone with the URL can hit your webhook. Don't skip this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1: Header-based auth.&lt;/strong&gt; In the Webhook node, set Authentication to "Header Auth," then create a credential with a secret key. The sender includes that key in a custom header (e.g. &lt;code&gt;x-api-key&lt;/code&gt;). n8n rejects requests that don't match.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2: Manual validation in a Function node&lt;/strong&gt; right after the webhook, useful when you need custom logic (like verifying a Stripe signature):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&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="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-webhook-signature&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;expected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-expected-signature-or-computed-hmac&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;expected&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Invalid webhook signature&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;$input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&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;Option 3: IP allowlisting&lt;/strong&gt; at the reverse proxy level (Caddy/Nginx) if you're self-hosting — this is the approach I use on my own n8n instance, since it stops unauthorized traffic before it even reaches the workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  A real pattern: webhook → branch → respond
&lt;/h2&gt;

&lt;p&gt;Here's a structure I use constantly for client support/lead workflows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Webhook&lt;/strong&gt; receives the event (e.g. a new lead from a landing page form)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Function node&lt;/strong&gt; normalizes and validates the payload:
&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&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="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;json&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Missing required fields&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&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="na"&gt;json&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unknown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;receivedAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&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;ol&gt;
&lt;li&gt;
&lt;strong&gt;IF node&lt;/strong&gt; branches on whether validation passed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Respond to Webhook node&lt;/strong&gt; sends back a proper status code and message, decoupled from whatever happens downstream (CRM push, Slack alert, email)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Splitting validation from the response like this means your webhook always replies fast and cleanly, even if the rest of the workflow (API calls, enrichment, database writes) takes longer or occasionally fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing without breaking production
&lt;/h2&gt;

&lt;p&gt;Don't test against your live production URL if the workflow is already active and doing real work. Instead:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Duplicate the workflow temporarily, or&lt;/li&gt;
&lt;li&gt;Use a tool like Postman / Insomnia / &lt;code&gt;curl&lt;/code&gt; against the &lt;strong&gt;test URL&lt;/strong&gt; while the workflow is open in the editor, or&lt;/li&gt;
&lt;li&gt;Add a temporary "test mode" branch using an IF node checking for a special header you only send manually&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A quick curl example for testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://your-n8n-instance.com/webhook/onboarding-signup &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: your-secret-key"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name": "Jane Doe", "email": "jane@example.com", "source": "landing-page"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A few things that trip people up
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Activated vs. saved&lt;/strong&gt;: a workflow with a webhook only listens on the production URL once it's toggled "Active" in the top right. Saving alone isn't enough.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-hosted instances need a public reachable URL.&lt;/strong&gt; If you're testing locally without a tunnel (ngrok, Cloudflare Tunnel), external services can't reach you. I run n8n on a VPS behind Caddy specifically so production webhooks are always reachable without extra tunneling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Webhook node timeouts&lt;/strong&gt;: if your logic takes too long and you used "When Last Node Finishes," the sender might time out and retry, causing duplicate processing. Build idempotency checks (e.g. dedupe by event ID) if the sender retries on timeout.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Webhooks are the backbone of any real-time automation in n8n. Once you're comfortable with triggering on inbound events, validating payloads, and responding correctly, you can connect n8n to literally anything that can make an HTTP request — which, in 2026, is everything.&lt;/p&gt;

&lt;p&gt;If you're building client-facing automations, the validation and security steps aren't optional polish — they're the difference between a workflow that survives contact with the real world and one that breaks (or gets abused) the first week it's live.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Build AI Agents in n8n: Replace Workflows With Claude Reasoning in 2026</title>
      <dc:creator>Christian Mbah</dc:creator>
      <pubDate>Fri, 12 Jun 2026 18:12:50 +0000</pubDate>
      <link>https://dev.to/chrismbah/how-to-build-ai-agents-in-n8n-replace-workflows-with-claude-reasoning-in-2026-3ljp</link>
      <guid>https://dev.to/chrismbah/how-to-build-ai-agents-in-n8n-replace-workflows-with-claude-reasoning-in-2026-3ljp</guid>
      <description>&lt;p&gt;Everyone's building automation with n8n, but most of it doesn't actually work in production.&lt;/p&gt;

&lt;p&gt;Your workflow handles 60% of cases perfectly. Then reality hits an edge case and the whole thing breaks. It's either a customer's message doesn't match your expected pattern, or a decision needs context your rules don't capture. &lt;/p&gt;

&lt;p&gt;Suddenly someone's babysitting an automated process that was supposed to be autonomous.&lt;/p&gt;

&lt;p&gt;That's the old automation model. Here's what changed in 2026: &lt;strong&gt;you can now layer AI agents into your n8n workflows&lt;/strong&gt;, turning rigid rule-based automation into intelligent systems that actually reason.&lt;/p&gt;

&lt;p&gt;This guide shows you how.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Workflows Alone Aren't Enough (And When to Use AI Agents)
&lt;/h2&gt;

&lt;p&gt;A workflow is deterministic. You define: trigger → condition → action → done.&lt;/p&gt;

&lt;p&gt;Lead comes in&lt;/p&gt;

&lt;p&gt;→ Check if budget &amp;gt;= $10k&lt;/p&gt;

&lt;p&gt;→ Check if company size &amp;gt;= 50 people&lt;/p&gt;

&lt;p&gt;→ Check if they mentioned pain point&lt;/p&gt;

&lt;p&gt;→ If all true: "hot lead"&lt;/p&gt;

&lt;p&gt;→ Else: "cold lead"&lt;/p&gt;

&lt;p&gt;This works until it doesn't. A $5k budget from a 10-person startup solving a critical problem looks cold by your rules. But that's actually your best customer.&lt;/p&gt;

&lt;p&gt;An AI agent is different. Instead of matching rules, it &lt;strong&gt;reads context, understands nuance, and reasons about what to do&lt;/strong&gt;. When it encounters something unexpected, it doesn't break, but escalates with reasoning attached.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use AI agents in n8n:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lead qualification (understanding intent, not just matching rules)&lt;/li&gt;
&lt;li&gt;Customer support triage (categorizing complex requests, not just keywords)&lt;/li&gt;
&lt;li&gt;Data classification (making judgment calls, not just pattern matching)&lt;/li&gt;
&lt;li&gt;Content routing (understanding context, not just tagging)&lt;/li&gt;
&lt;li&gt;Decision workflows (anything that needs human judgment, but 80% of cases are obvious)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What's Different in 2026: The Technology That Makes This Feasible
&lt;/h2&gt;

&lt;p&gt;Three major releases changed what's possible:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. &lt;a href="https://claude.com/blog/claude-managed-agents" rel="noopener noreferrer"&gt;Claude Managed Agents&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can now run AI agents on a schedule without n8n as your orchestration layer. More importantly: credentials are stored in a vault, so your agent never sees your actual API keys. This solves the security problem that used to require complex engineering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. &lt;a href="https://blog.n8n.io/introducing-n8n-2-0/" rel="noopener noreferrer"&gt;n8n 2.0 with AI Workflow Builder&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;n8n shipped two massive improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AI Workflow Builder&lt;/strong&gt;: Describe what you want in English, it generates the workflow scaffold&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;10x faster database performance&lt;/strong&gt;: Makes complex agent loops practical at scale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Model Efficiency Explosion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/chrismbah/claude-fable-5-is-here-heres-what-actually-matters-for-developers-29ko"&gt;Claude Fable 5&lt;/a&gt; is more capable than anything public last year. But also: smaller models (Mistral, Qwen) now match GPT-4 on benchmarks. The cost argument against AI agents is dead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bottom line:&lt;/strong&gt; Building AI agents in n8n in 2026 is faster, cheaper, and more secure than it was 6 months ago.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Build an AI Agent in n8n: Step-by-Step
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Identify Your Brittle Workflow
&lt;/h3&gt;

&lt;p&gt;Start by finding the part of your current automation that fails most often. This is usually where you have 10+ conditional branches because "it could mean this or that."&lt;/p&gt;

&lt;p&gt;Example: Your lead scoring workflow has rules for 15 different scenarios, but leads still get misrouted. This is your candidate for an agent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Design Your Agent's Context
&lt;/h3&gt;

&lt;p&gt;An AI agent is only as good as the context you give it. Don't just feed it the immediate input — give it your business rules, past decisions, and what success looks like.&lt;/p&gt;

&lt;p&gt;For a lead qualification agent, that might be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your ideal customer profile (ICP)&lt;/li&gt;
&lt;li&gt;Recent deals you won (with why they won)&lt;/li&gt;
&lt;li&gt;Common objections you see&lt;/li&gt;
&lt;li&gt;Your pricing tiers&lt;/li&gt;
&lt;li&gt;Your sales process&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Store this in a document, Google Sheet, or Pinecone vector database. Your agent will pull from it when making decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Add the Claude Agent Node to n8n
&lt;/h3&gt;

&lt;p&gt;In your n8n workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a new HTTP Request node&lt;/strong&gt; that calls Claude's API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass your context&lt;/strong&gt; (from Step 2) in the system prompt&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send the incoming data&lt;/strong&gt; (lead info, customer message, etc.) as the user message&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parse Claude's response&lt;/strong&gt; — it should include reasoning + decision&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;"&lt;br&gt;
You are a lead qualification expert. Your job is to score leads as Hot/Warm/Cold.&lt;br&gt;
Here is our ideal customer profile:&lt;/p&gt;

&lt;p&gt;[Insert ICP details]&lt;br&gt;
Here are examples of leads we qualified:&lt;/p&gt;

&lt;p&gt;[Insert past deals with outcomes]&lt;br&gt;
Now evaluate this lead and score them:&lt;/p&gt;

&lt;p&gt;[Insert incoming lead data]&lt;br&gt;
Respond in JSON format:&lt;/p&gt;

&lt;p&gt;{&lt;/p&gt;

&lt;p&gt;"score": "hot" | "warm" | "cold",&lt;/p&gt;

&lt;p&gt;"reasoning": "why this score",&lt;/p&gt;

&lt;p&gt;"confidence": 0-100,&lt;/p&gt;

&lt;p&gt;"next_action": "what to do with this lead"&lt;/p&gt;

&lt;p&gt;}&lt;br&gt;
"&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Route Based on the Agent's Decision
&lt;/h3&gt;

&lt;p&gt;Connect the Claude response to your routing logic:&lt;/p&gt;

&lt;p&gt;Claude Agent Output&lt;/p&gt;

&lt;p&gt;→ Score = "hot"? → Route to immediate sales outreach + personalized email&lt;/p&gt;

&lt;p&gt;→ Score = "warm"? → Add to nurture sequence&lt;/p&gt;

&lt;p&gt;→ Score = "cold" but high confidence? → Archive&lt;/p&gt;

&lt;p&gt;→ Score = "cold" but low confidence? → Escalate to human with full reasoning&lt;/p&gt;

&lt;p&gt;The key: when confidence is low, escalate with reasoning, not confusion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Log Everything and Iterate
&lt;/h3&gt;

&lt;p&gt;Every wrong decision is data. Log:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What the agent got wrong&lt;/li&gt;
&lt;li&gt;Why it was wrong&lt;/li&gt;
&lt;li&gt;What context would have helped&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After a week of data, you'll see patterns. Add that context to your prompt and redeploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Example: Lead Scoring That Works
&lt;/h2&gt;

&lt;p&gt;Here's what I built last week using Claude + n8n:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The old way (pure workflow):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;15 conditional branches&lt;/li&gt;
&lt;li&gt;Works 70% of the time&lt;/li&gt;
&lt;li&gt;Edge cases break silently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The new way (Claude agent in n8n):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Lead fills form → n8n captures data&lt;/li&gt;
&lt;li&gt;n8n calls Claude with: lead details + your website content + past deal data&lt;/li&gt;
&lt;li&gt;Claude scores: Hot/Warm/Cold with reasoning&lt;/li&gt;
&lt;li&gt;If Hot: immediate HubSpot entry + personalized email drafted&lt;/li&gt;
&lt;li&gt;If Warm: added to nurture sequence&lt;/li&gt;
&lt;li&gt;If Cold but uncertain: escalated for human review with Claude's reasoning included&lt;/li&gt;
&lt;li&gt;If Cold and confident: archived automatically&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; 95% accuracy instead of 70%, plus every escalation includes reasoning so humans aren't confused.&lt;/p&gt;

&lt;p&gt;Time saved: Lead goes from form → CRM → first email in under 60 seconds. No manual work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Pattern That Scales: Human-in-the-Loop AI Agents
&lt;/h2&gt;

&lt;p&gt;Here's what actually works in production:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't build fully autonomous AI agents.&lt;/strong&gt; Build agents with approval points where it costs to be wrong.&lt;/p&gt;

&lt;p&gt;If a decision involves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Money (e.g., discounting below margin)&lt;/li&gt;
&lt;li&gt;Legal liability (e.g., compliance decisions)&lt;/li&gt;
&lt;li&gt;Customer trust (e.g., service escalations)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then add a human approval node. Let the agent prepare the decision with full reasoning. A human signs off in 30 seconds instead of doing the work from scratch.&lt;/p&gt;

&lt;p&gt;This isn't "baby AI." This is intelligent leverage. Your team moves faster because the agent handles grunt work. Your customer gets better service because decisions aren't made by dumb rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to Start Building AI Agents in n8n
&lt;/h2&gt;

&lt;p&gt;Don't rebuild everything. Do this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pick one workflow&lt;/strong&gt; with messy branching logic or frequent exceptions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add one Claude node&lt;/strong&gt; to handle the reasoning for that piece&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Let it run for one week&lt;/strong&gt; — see what it gets right and wrong&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iterate&lt;/strong&gt; — add context based on what failed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scale once you understand the pattern&lt;/strong&gt; — then apply to other workflows&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Tools you need:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;n8n (free self-hosted version works)&lt;/li&gt;
&lt;li&gt;Claude API key ($5-25/month usually)&lt;/li&gt;
&lt;li&gt;Your business context (ideally in a document or vector DB)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Time to first working agent:&lt;/strong&gt; 2-4 hours if you know your business rules well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Mistakes to Avoid
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Don't:&lt;/strong&gt; Pass raw data to Claude without context. It will hallucinate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do:&lt;/strong&gt; Include your business rules, past examples, and what success looks like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't:&lt;/strong&gt; Expect 100% accuracy on first try. AI agents improve with iteration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do:&lt;/strong&gt; Log failures and add context for next iteration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't:&lt;/strong&gt; Make every decision autonomous. Some things need human judgment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do:&lt;/strong&gt; Use agents to prepare decisions, not make them when trust/money is on the line.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;In 2026, the choice isn't "automation or no automation." It's "dumb rules or intelligent reasoning?"&lt;/p&gt;

&lt;p&gt;Workflows that branch on conditions are done for anything complicated. AI agents that reason are the default now.&lt;/p&gt;

&lt;p&gt;If you're building n8n automation that's supposed to work in production, stop wiring conditions. Start building agents.&lt;/p&gt;

&lt;p&gt;Claude Managed Agents + n8n + your business context = automation that actually handles reality.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Ready to try this?&lt;/strong&gt; Start with one workflow this week. Add a Claude node. See what happens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Already building AI agents?&lt;/strong&gt; What's your biggest bottleneck — is it context, escalations, or something else? Drop it in the comments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Want the specific n8n setup guide?&lt;/strong&gt; I'm writing the next post as a complete walkthrough with template workflows. Follow for updates.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>openai</category>
      <category>automation</category>
    </item>
    <item>
      <title>Claude Fable 5 Is Here. Here's What Actually Matters for Developers 👨🏾‍💻</title>
      <dc:creator>Christian Mbah</dc:creator>
      <pubDate>Tue, 09 Jun 2026 23:22:06 +0000</pubDate>
      <link>https://dev.to/chrismbah/claude-fable-5-is-here-heres-what-actually-matters-for-developers-29ko</link>
      <guid>https://dev.to/chrismbah/claude-fable-5-is-here-heres-what-actually-matters-for-developers-29ko</guid>
      <description>&lt;p&gt;Anthropic dropped two models today.&lt;br&gt;
Most people are focused on the wrong one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What launched:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Fable 5&lt;/strong&gt; — the public-facing Mythos-class model. Available on Pro, Max, Team, and Enterprise right now. Stronger than anything Anthropic has released publicly. &lt;/p&gt;

&lt;p&gt;Better at long-context, agentic coding, vision, and knowledge work. The longer and more complex the task, the bigger the gap between Fable and previous models.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mythos 5&lt;/strong&gt; — same architecture, fewer restrictions. Going out through Project Glasswing to a small group of security providers and government institutions only. You're not getting access to this one. Neither am I.&lt;/p&gt;

&lt;h2&gt;
  
  
  The catch nobody's leading with:
&lt;/h2&gt;

&lt;p&gt;Fable 5 is free on your subscription until &lt;strong&gt;June 22&lt;/strong&gt;. On June 23 it moves to usage credits. &lt;/p&gt;

&lt;p&gt;Pricing is $10/million input tokens and $50/million output tokens — double what you're paying now for Opus.&lt;/p&gt;

&lt;p&gt;You have 12 days to hammer it before it costs real money.&lt;/p&gt;

&lt;p&gt;What's actually different for developers:&lt;/p&gt;

&lt;p&gt;The safeguard fallback is interesting architecture. Sensitive queries — cybersecurity, biology, chemistry — silently fall back to Opus 4.8. &lt;/p&gt;

&lt;p&gt;Anthropic says this triggers in under 5% of sessions. If you're building in those domains, test your workflows now because your production behaviour may shift depending on which model actually responds.&lt;/p&gt;

&lt;p&gt;For agentic work the jump is real. I build automation workflows with n8n and Claude and the longer the chain, the more Fable pulls ahead. Multi-step reasoning, document processing, complex conditionals — noticeably sharper.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm actually testing this week:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Multi-agent loops on my n8n stack&lt;/li&gt;
&lt;li&gt;Long-context RAG retrieval quality vs Opus 4.7&lt;/li&gt;
&lt;li&gt;Vision tasks on mixed document types&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The bigger picture:
&lt;/h2&gt;

&lt;p&gt;Mythos-class capability is now public. With guardrails, yes — but the ceiling just moved up significantly. The question isn't whether Mythos ever ships publicly. It's how fast this capability tier becomes the default baseline.&lt;/p&gt;

&lt;p&gt;Use the next 12 days well.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What are you testing Fable 5 on first? Drop it in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claude</category>
      <category>llm</category>
      <category>news</category>
    </item>
    <item>
      <title>Build an AI-Powered Lead Follow-Up System with n8n and OpenAI 🚀</title>
      <dc:creator>Christian Mbah</dc:creator>
      <pubDate>Mon, 08 Jun 2026 21:52:08 +0000</pubDate>
      <link>https://dev.to/chrismbah/build-an-ai-powered-lead-follow-up-system-with-n8n-and-openai-40n4</link>
      <guid>https://dev.to/chrismbah/build-an-ai-powered-lead-follow-up-system-with-n8n-and-openai-40n4</guid>
      <description>&lt;p&gt;Let's build an AI-powered lead follow-up system today on n8n.&lt;/p&gt;

&lt;p&gt;A webhook captures the lead. OpenAI writes a personalized email. &lt;br&gt;
Gmail sends it. Google Sheets logs it.&lt;/p&gt;

&lt;p&gt;Four nodes that runs in under 10 seconds with zero humans in the loop.&lt;/p&gt;

&lt;p&gt;By the end of this post you'll have a fully working workflow you can import directly into n8n with the JSON export is at the bottom.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you'll learn:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to capture lead data via a webhook trigger&lt;/li&gt;
&lt;li&gt;How to use OpenAI (gpt-4o-mini) to write personalised follow-up emails&lt;/li&gt;
&lt;li&gt;How to send automatically via Gmail&lt;/li&gt;
&lt;li&gt;How to log every lead and email sent to Google Sheets&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What You're Building
&lt;/h2&gt;

&lt;p&gt;Here's the flow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Webhook → OpenAI (personalize email) → Gmail (send) → Google Sheets (log)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A lead submits a form anywhere — your website, Tally, Typeform, whatever. The webhook fires, OpenAI reads their data and writes a personalized follow-up email, Gmail sends it automatically and finally Google Sheets logs the lead and the email that was sent, so you have a record.&lt;/p&gt;

&lt;p&gt;No human in the loop. The whole thing runs in under 10 seconds.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;n8n account (cloud or self-hosted — either works)&lt;/li&gt;
&lt;li&gt;OpenAI API key&lt;/li&gt;
&lt;li&gt;A Gmail account connected to n8n&lt;/li&gt;
&lt;li&gt;A Google Sheet to log leads to&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1 — The Webhook Trigger
&lt;/h2&gt;

&lt;p&gt;Create a new workflow in n8n. Add your first node: &lt;strong&gt;Webhook&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Set the HTTP Method to &lt;code&gt;POST&lt;/code&gt;. n8n will generate a unique URL for you. Copy it — this is what your form will POST to.&lt;/p&gt;

&lt;p&gt;Your webhook will receive a payload that looks something like this:&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;"Chris Mbah"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"chris@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"company"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Endy Studios"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Founder"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Looking for help automating our lead pipeline"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The field names will match whatever your form sends. Keep that in mind when configuring the nodes below — you'll reference these fields by name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test it:&lt;/strong&gt; Click "Listen for test event" in n8n, then send a test POST request using Postman or a simple curl command. Once n8n receives it, the data shows up in the node output and you can reference it downstream.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://your-n8n-webhook-url &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"name":"Chris Mbah","email":"chris@example.com","company":"Endy Studios","role":"Founder","message":"Looking for help automating our lead pipeline"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2 — OpenAI (Write the Personalised Email)
&lt;/h2&gt;

&lt;p&gt;Add an &lt;strong&gt;OpenAI&lt;/strong&gt; node. Connect it to the Webhook node.&lt;/p&gt;

&lt;p&gt;Set the resource to &lt;code&gt;Message&lt;/code&gt; and the operation to &lt;code&gt;Complete&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Model&lt;/strong&gt; field, use &lt;code&gt;gpt-4o-mini&lt;/code&gt;. It's fast, cheap, and more than capable for email writing.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Prompt&lt;/strong&gt; field, this is where the personalisation happens. Use n8n's expression syntax to pull in the webhook data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are an AI assistant helping a freelance AI automation consultant follow up with new leads.

Write a short, professional follow-up email to a lead with the following details:

Name: {{ $json.name }}
Company: {{ $json.company }}
Role: {{ $json.role }}
Message they sent: {{ $json.message }}

Guidelines:
- Keep it under 120 words
- Sound human, not like a template
- Acknowledge what they said specifically
- End with a clear CTA to book a 20-minute call
- Do not use subject lines or greetings like "Dear" — start directly
- Return only the email body, nothing else
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set &lt;strong&gt;Max Tokens&lt;/strong&gt; to &lt;code&gt;300&lt;/code&gt;. That's plenty for a short follow-up email and keeps your API costs low.&lt;/p&gt;

&lt;p&gt;The node output will be a single string — the email body. You'll reference it in the next step as &lt;code&gt;{{ $json.message.content }}&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3 — Gmail (Send the Email)
&lt;/h2&gt;

&lt;p&gt;Add a &lt;strong&gt;Gmail&lt;/strong&gt; node. Connect it to the OpenAI node.&lt;/p&gt;

&lt;p&gt;Set the operation to &lt;code&gt;Send&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Configure the fields:&lt;/p&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;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;To&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{{ $('Webhook').item.json.email }}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Subject&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Re: Your enquiry — let's talk automation&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Message&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{{ $json.message.content }}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Send As&lt;/td&gt;
&lt;td&gt;HTML or Plain Text (your preference)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;To&lt;/code&gt; field references the original webhook data directly — not the OpenAI output — so make sure you're pulling from the right node. In n8n, you can reference any previous node's output using &lt;code&gt;$('Node Name').item.json.fieldName&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One thing worth noting:&lt;/strong&gt; the subject line above is generic. You can make it dynamic too. Ask OpenAI to return a subject line alongside the body by adjusting your prompt to output JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JSON&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;object&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;with&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;two&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;fields:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"subject"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;short,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;specific&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;subject&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;line&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;(max&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;words)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"body"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;email&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;body&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;only&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;valid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;JSON.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;No&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;markdown.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;No&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;backticks.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then parse it in n8n with a &lt;strong&gt;Code&lt;/strong&gt; node before passing to Gmail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&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="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subject&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4 — Google Sheets (Log the Lead)
&lt;/h2&gt;

&lt;p&gt;Add a &lt;strong&gt;Google Sheets&lt;/strong&gt; node. Connect it to the Gmail node.&lt;/p&gt;

&lt;p&gt;Set the operation to &lt;code&gt;Append Row&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Select your spreadsheet and sheet. Then map the columns:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Column&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{{ $('Webhook').item.json.name }}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Email&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{{ $('Webhook').item.json.email }}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Company&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{{ $('Webhook').item.json.company }}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Role&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{{ $('Webhook').item.json.role }}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Message&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{{ $('Webhook').item.json.message }}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Email Sent&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{{ $('OpenAI').item.json.message.content }}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Timestamp&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{{ $now }}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This gives you a running log of every lead and exactly what was sent to them. Useful if you ever need to review what went out, or hand things off to a client.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Full Workflow
&lt;/h2&gt;

&lt;p&gt;Here's what the complete canvas 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;[Webhook] → [OpenAI] → [Gmail] → [Google Sheets]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Four nodes. Linear. No branching required for this version.&lt;/p&gt;

&lt;p&gt;If you want to add branching later — for example, only email leads who mention a specific intent, or route high-value leads to a Slack notification — you'd add an &lt;strong&gt;IF&lt;/strong&gt; node between Webhook and OpenAI and split the flow from there.&lt;/p&gt;




&lt;h2&gt;
  
  
  Activating the Workflow
&lt;/h2&gt;

&lt;p&gt;Once everything is tested and working, toggle the workflow to &lt;strong&gt;Active&lt;/strong&gt; in the top right.&lt;/p&gt;

&lt;p&gt;From this point on, every POST request to your webhook URL triggers the full sequence automatically. No need to keep the n8n editor open.&lt;/p&gt;

&lt;p&gt;If you're self-hosting, make sure your n8n instance is always running. If you're on cloud, it handles that for you.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Costs to Run
&lt;/h2&gt;

&lt;p&gt;At current OpenAI pricing, &lt;code&gt;gpt-4o-mini&lt;/code&gt; costs roughly $0.15 per million input tokens and $0.60 per million output tokens.&lt;/p&gt;

&lt;p&gt;A single lead follow-up — prompt + response — uses around 300–400 tokens total.&lt;/p&gt;

&lt;p&gt;That's roughly &lt;strong&gt;$0.0001 per lead.&lt;/strong&gt; You could process 10,000 leads for about $1.&lt;/p&gt;

&lt;p&gt;Gmail is free. Google Sheets is free. n8n cloud has a free tier that covers this comfortably.&lt;/p&gt;

&lt;p&gt;This entire system runs at near-zero cost.&lt;/p&gt;

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




&lt;h2&gt;
  
  
  Full JSON Export
&lt;/h2&gt;

&lt;p&gt;Import this directly into n8n. Go to your workflow, click the menu (⋯), select &lt;strong&gt;Import from JSON&lt;/strong&gt;, and paste this in. Swap in your own credentials and webhook URL.&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;"AI Lead Follow-Up System"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"nodes"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&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;"httpMethod"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"POST"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lead-followup"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"responseMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"onReceived"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"webhook-node"&lt;/span&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;"Webhook"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.webhook"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;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;"position"&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="mi"&gt;250&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&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;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"chat"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"operation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"complete"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gpt-4o-mini"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"messages"&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;"values"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"You are an AI assistant helping a freelance AI automation consultant follow up with new leads.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Write a short, professional follow-up email to a lead with the following details:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Name: {{ $json.name }}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Company: {{ $json.company }}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Role: {{ $json.role }}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Message they sent: {{ $json.message }}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Guidelines:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;- Keep it under 120 words&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;- Sound human, not like a template&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;- Acknowledge what they said specifically&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;- End with a clear CTA to book a 20-minute call&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;- Do not use subject lines or greetings like &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Dear&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; — start directly&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;- Return only the email body, nothing else"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"options"&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;"maxTokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"openai-node"&lt;/span&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;"OpenAI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@n8n/n8n-nodes-langchain.openAi"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;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;"position"&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="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&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;"operation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"send"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"toList"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"={{ $('Webhook').item.json.email }}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"subject"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Re: Your enquiry — let's talk automation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"={{ $json.message.content }}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gmail-node"&lt;/span&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;"Gmail"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.gmail"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&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="mi"&gt;750&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&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;"operation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"append"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"documentId"&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;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"YOUR_GOOGLE_SHEET_ID"&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;"sheetName"&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;"value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sheet1"&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;"columns"&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;"mappingMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"defineBelow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"value"&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;"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;"={{ $('Webhook').item.json.name }}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"={{ $('Webhook').item.json.email }}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Company"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"={{ $('Webhook').item.json.company }}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"={{ $('Webhook').item.json.role }}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"={{ $('Webhook').item.json.message }}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Email Sent"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"={{ $('OpenAI').item.json.message.content }}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"={{ $now }}"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sheets-node"&lt;/span&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;"Google Sheets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"n8n-nodes-base.googleSheets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"typeVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"position"&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="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"connections"&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;"Webhook"&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;"main"&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;"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;"OpenAI"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;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="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"OpenAI"&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;"main"&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;"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;"Gmail"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;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="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Gmail"&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;"main"&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;"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;"Google Sheets"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"index"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;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="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Where to Take This Next
&lt;/h2&gt;

&lt;p&gt;This is the foundation. Once it's running, there are a few natural extensions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add lead scoring.&lt;/strong&gt; Ask OpenAI to rate the lead 1–10 based on their message and role before writing the email. Route low-score leads to a different, shorter email. Route high-score leads to also ping your Slack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add a delay.&lt;/strong&gt; If you want the email to feel less instant (some people find immediate auto-replies suspicious), add a &lt;strong&gt;Wait&lt;/strong&gt; node between OpenAI and Gmail. Set it to 10–15 minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connect it to your CRM.&lt;/strong&gt; Swap Google Sheets for a HubSpot or Airtable node. Same logic, cleaner data management.&lt;/p&gt;

&lt;p&gt;But start with what's here. Get it running. See leads come in and emails go out automatically.&lt;/p&gt;

&lt;p&gt;That's the point of automation — not the complexity. The simplicity.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Building more of these publicly. Follow along if you want to see what comes next.&lt;/em&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  n8n #automation #openai #tutorial #nocode #webdev #javascript #productivity
&lt;/h1&gt;

</description>
      <category>openai</category>
      <category>automation</category>
      <category>ai</category>
      <category>claude</category>
    </item>
    <item>
      <title>n8n Tutorial: How to Build Your First No-Code Automation Workflow in 2026</title>
      <dc:creator>Christian Mbah</dc:creator>
      <pubDate>Sat, 06 Jun 2026 19:22:03 +0000</pubDate>
      <link>https://dev.to/chrismbah/n8n-tutorial-how-to-build-your-first-no-code-automation-workflow-in-2026-3dfi</link>
      <guid>https://dev.to/chrismbah/n8n-tutorial-how-to-build-your-first-no-code-automation-workflow-in-2026-3dfi</guid>
      <description>&lt;p&gt;You know that feeling when you're doing the same task over and over again, and you think "there has to be a better way"?&lt;/p&gt;

&lt;p&gt;That's exactly what n8n solves. If you've been wondering how to automate tasks without writing code, or you're curious about business automation platforms, you're in the right place.&lt;/p&gt;

&lt;p&gt;A few months ago, I would've told you that real automation required code. I was wrong. n8n changed how I think about solving problems, and I want to walk you through it.&lt;/p&gt;

&lt;p&gt;This post is for anyone—whether you code or not—curious about automation but unsure where to start.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is n8n? A No-Code Automation Platform Explained
&lt;/h2&gt;

&lt;p&gt;Think of n8n like a middleman that helps different apps talk to each other and do work automatically.&lt;/p&gt;

&lt;p&gt;Let me give you a real example. Say you run a business and you get leads through a Google Form. Right now, here's what happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Someone fills out the form&lt;/li&gt;
&lt;li&gt;You manually check it&lt;/li&gt;
&lt;li&gt;You copy the information to your CRM&lt;/li&gt;
&lt;li&gt;You send them a welcome email&lt;/li&gt;
&lt;li&gt;You log it somewhere for follow-up&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's five separate steps. Every single time. All day.&lt;/p&gt;

&lt;p&gt;With n8n, that entire sequence happens automatically the moment someone fills out the form.&lt;/p&gt;

&lt;p&gt;Form submission → CRM entry → Welcome email → Log created → Done.&lt;/p&gt;

&lt;p&gt;No one has to touch it. The workflow just runs in the background.&lt;/p&gt;

&lt;p&gt;What makes n8n special is that it's not just "connect this to that." It can think. It can ask questions like "Is this a hot lead or a cold lead?" and send people different directions. It can transform data, wait for responses, send multiple messages—all without you writing a single line of code.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Think About n8n Automation: Workflows, Nodes, and Triggers
&lt;/h2&gt;

&lt;p&gt;Before we get technical, understand how automation actually works. It's three simple ideas:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workflows&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A workflow is just a plan. Your plan for what should happen and when.&lt;/p&gt;

&lt;p&gt;"When a form is submitted, add to CRM and send an email" is a workflow. It's the thing you want to automate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nodes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A node is a single step in that plan. "Add to CRM" is one node. "Send an email" is another node.&lt;/p&gt;

&lt;p&gt;You build workflows by connecting nodes together. Each node does one job.&lt;/p&gt;

&lt;p&gt;Think of it like a recipe. A workflow is the entire recipe. Nodes are the individual steps (mix flour, add eggs, bake, etc.).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Triggers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A trigger is the "when" that starts everything.&lt;/p&gt;

&lt;p&gt;"When a form is submitted" is a trigger. "When someone replies to an email" is a trigger. "Every morning at 8 AM" is a trigger.&lt;/p&gt;

&lt;p&gt;Without a trigger, nothing happens. The trigger is what wakes up your workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started: Setting Up Your n8n Account
&lt;/h2&gt;

&lt;p&gt;Before you build anything, you need to get into n8n. The good news? It takes about 5 minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Sign up&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go to &lt;a href="https://n8n.cloud" rel="noopener noreferrer"&gt;n8n.cloud&lt;/a&gt; and click "Sign up."&lt;/p&gt;

&lt;p&gt;You'll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Email address&lt;/li&gt;
&lt;li&gt;Password&lt;/li&gt;
&lt;li&gt;That's it. No credit card required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;n8n offers a free 14-day trial on their cloud version. After that, free tier plans exist, but you have room to explore without paying.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Verify your email&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check your inbox. n8n sends you a verification email. Click the link, and you're in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Meet your dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After verification, you'll land on your n8n dashboard. It loads in seconds. You'll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your workspace name (you can change this later)&lt;/li&gt;
&lt;li&gt;A big button that says "Create Workflow" or "Start from Scratch"&lt;/li&gt;
&lt;li&gt;A list of pre-built templates (you can ignore these for now)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. You're ready to build.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build Your First n8n Workflow: A Step-by-Step Tutorial
&lt;/h2&gt;

&lt;p&gt;Now let me show you something you can actually build in 10 minutes.&lt;/p&gt;

&lt;p&gt;Imagine: &lt;strong&gt;Every time someone fills out a contact form on your website, you get a Slack message.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's how you'd think about it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trigger:&lt;/strong&gt; Someone submits a form&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Action:&lt;/strong&gt; Send a Slack message&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. Two steps. In n8n, that's two nodes connected together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create your workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Click "Create Workflow" (or "Start from Scratch").&lt;/p&gt;

&lt;p&gt;You'll see a blank canvas. It's intimidating at first, but it's just empty space waiting for you to add things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Add your trigger (the form)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;+ button&lt;/strong&gt; in the center of the canvas.&lt;/p&gt;

&lt;p&gt;Search for your form provider. Let's say you use &lt;strong&gt;Tally&lt;/strong&gt; for your contact form.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click "Tally"&lt;/li&gt;
&lt;li&gt;Click "On Form Submit" (this is your trigger)&lt;/li&gt;
&lt;li&gt;A node appears on your canvas labeled "Tally"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Authenticate Tally&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Click the Tally node.&lt;/p&gt;

&lt;p&gt;On the right side, you'll see a panel that says "Authenticate." Click it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;n8n opens a popup asking you to log into Tally&lt;/li&gt;
&lt;li&gt;You log in&lt;/li&gt;
&lt;li&gt;You authorize n8n to access your Tally account&lt;/li&gt;
&lt;li&gt;The popup closes. You're authenticated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Back on the canvas, the Tally node now shows you a list of your Tally forms. Select the form you want to monitor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Add your action (Slack notification)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;+ button&lt;/strong&gt; again, this time to the right of the Tally node.&lt;/p&gt;

&lt;p&gt;Search for "Slack."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click "Slack"&lt;/li&gt;
&lt;li&gt;Click "Send Message" (this is your action)&lt;/li&gt;
&lt;li&gt;A node appears next to Tally labeled "Slack"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Authenticate Slack&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Click the Slack node.&lt;/p&gt;

&lt;p&gt;On the right side, click "Authenticate."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;n8n opens a popup asking you to log into Slack&lt;/li&gt;
&lt;li&gt;You log in&lt;/li&gt;
&lt;li&gt;You authorize n8n&lt;/li&gt;
&lt;li&gt;The popup closes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Configure the Slack message&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Still in the Slack node panel, you'll see options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Channel:&lt;/strong&gt; Select the Slack channel where you want the message (try #general or #notifications)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Message:&lt;/strong&gt; Type what you want the message to say. For now, something simple like "New form submission received!"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can make it dynamic later (pulling the person's name from the form, etc.), but keep it simple for now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7: Connect the nodes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the fun part. On the canvas, you should see your Tally node on the left and your Slack node on the right.&lt;/p&gt;

&lt;p&gt;On the right side of the Tally node, there's a small dot. Click and drag a line from that dot to the left side of the Slack node.&lt;/p&gt;

&lt;p&gt;You'll see a connection line. This tells n8n: "When Tally triggers, send to Slack."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8: Test your workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At the top of the canvas, click &lt;strong&gt;"Test Workflow"&lt;/strong&gt; (or "Execute Workflow").&lt;/p&gt;

&lt;p&gt;n8n will pretend someone filled out your form and see if it can send the Slack message.&lt;/p&gt;

&lt;p&gt;If it works, you'll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A green checkmark on both nodes&lt;/li&gt;
&lt;li&gt;A message in Slack (in your chosen channel)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If something breaks, n8n will show you an error. It usually tells you exactly what went wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9: Activate your workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the test passes, click &lt;strong&gt;"Activate"&lt;/strong&gt; at the top right.&lt;/p&gt;

&lt;p&gt;Your workflow is now live. Every time someone fills out your Tally form, n8n automatically sends a message to Slack.&lt;/p&gt;

&lt;p&gt;And yes, it really is that &lt;em&gt;straightforward&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes n8n Powerful: Real Use Cases for No-Code Automation
&lt;/h2&gt;

&lt;p&gt;Here's the thing that blew my mind: once you understand these basics, you can build almost anything.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Qualify leads automatically.&lt;/strong&gt; The form comes in → n8n asks ChatGPT to score it → sends hot leads to your CRM and cold leads somewhere else&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send personalized follow-ups.&lt;/strong&gt; New customer → pull their info → send custom email → log it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep everything in sync.&lt;/strong&gt; Update Spreadsheet A → automatically updates Spreadsheet B, your CRM, and a backup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create alerts.&lt;/strong&gt; When something specific happens → notify the right person on Slack or email&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The automation isn't limited to simple "if X then Y" logic. n8n can handle complexity. It's just that most businesses don't need complexity—they need consistency.&lt;/p&gt;

&lt;p&gt;And that's where the real value is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started (Actually)
&lt;/h2&gt;

&lt;p&gt;Here's your action plan:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sign up&lt;/strong&gt; at &lt;a href="https://n8n.io" rel="noopener noreferrer"&gt;n8n.io&lt;/a&gt; (free cloud version is perfect to learn)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pick one repetitive task&lt;/strong&gt; you do manually every week&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Break it into steps:&lt;/strong&gt; What's the trigger? What are the actions? What apps are involved?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build it.&lt;/strong&gt; Add nodes, connect them, test, activate&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;See what happens.&lt;/strong&gt; Let it run for a week&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You'll be surprised how much time it saves.&lt;/p&gt;

&lt;p&gt;The hardest part isn't building automation in n8n. The hardest part is identifying what should be automated in the first place.&lt;/p&gt;

&lt;p&gt;Once you know what problem you're solving, n8n is just the tool to solve it.&lt;/p&gt;

&lt;h2&gt;
  
  
  One More Thing
&lt;/h2&gt;

&lt;p&gt;A lot of people think automation means you won't have to work. That's not true.&lt;/p&gt;

&lt;p&gt;Automation means you don't have to do repetitive work. You get to focus on the actual problems—the thinking, the strategy, the relationships.&lt;/p&gt;

&lt;p&gt;The boring stuff? Let n8n handle it.&lt;/p&gt;

&lt;p&gt;I'm building workflows constantly now. Some work perfectly. Some need tweaking. Some teach me something new about how the apps I'm using actually work.&lt;/p&gt;

&lt;p&gt;I'll be sharing those learnings here. Workflows I've built, problems I've solved, mistakes I've made.&lt;/p&gt;

&lt;p&gt;But the foundation? It's what you've just read.&lt;/p&gt;

&lt;p&gt;Start small. Build something. See it work.&lt;/p&gt;

&lt;p&gt;Everything else flows from there.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Have questions? Ask in the comments. I'm learning this alongside you, so let's figure it out together.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>openai</category>
      <category>automation</category>
      <category>ai</category>
      <category>claude</category>
    </item>
    <item>
      <title>How Developers Flatline Their Careers — And How to Avoid It</title>
      <dc:creator>Christian Mbah</dc:creator>
      <pubDate>Sat, 06 Dec 2025 18:59:27 +0000</pubDate>
      <link>https://dev.to/chrismbah/how-developers-flatline-their-careers-and-how-to-avoid-it-6li</link>
      <guid>https://dev.to/chrismbah/how-developers-flatline-their-careers-and-how-to-avoid-it-6li</guid>
      <description>&lt;p&gt;Software engineering is one of the most interesting career paths in the world today. In an ecosystem where technologies like artificial intelligence are becoming mainstream every day, it’s no wonder you probably ventured into it out of curiosity, learned tirelessly, and began building a career. Yes, it’s exciting and full of possibilities, but it can also be surprisingly stagnating if you don’t know the right steps to take.&lt;/p&gt;

&lt;p&gt;Why? Because software engineering is simply a path, and how you navigate it determines how far you go. For some, it may be a smooth upward slope, steadily rising toward impact and financial freedom. For others, a series of peaks and valleys, a rollercoaster of wins and failures. But for some, there’s an initial rise… followed by a long, flat line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtulekid8zx6quz3l77f.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtulekid8zx6quz3l77f.jpg" alt="Flatlining career software engineer" width="512" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In medical terms, flatlining means death; in software engineering, it means stagnation. The good news is stagnation isn’t permanent and with awareness, deliberate action, and the right mindset, growth is always possible. So here are 5 ways developers unintentionally flatline their careers, and how to avoid them:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Avoiding Communication
&lt;/h2&gt;

&lt;p&gt;You might be able to write bug-free code that works flawlessly, but if you can’t explain your decisions, ask the right questions, or even collaborate effectively, no one will notice. Soft skills aren’t optional in this field; they are the piece that turns programmers into problem solvers with a meaningful impact.&lt;/p&gt;

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

&lt;p&gt;Brilliant engineers can stagnate for years simply because they couldn’t articulate their thoughts or navigate team dynamics because they lack communication skills. I could even argue being invisible in a team is worse than making a mistake, because mistakes are noticed, corrected, and learned from, meanwhile if you're invisible, you're invisible. If you want to stunt your career progress, then reduce communication as much as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Relying on AI to Think for You
&lt;/h2&gt;

&lt;p&gt;AI is powerful — insanely powerful, but the truth is that AI only accelerates people who already think well. If you lack fundamentals, AI will become a crutch, not a jetpack.&lt;/p&gt;

&lt;p&gt;Rely on AI for every decision and your problem-solving muscles slowly deteriorate. You stop breaking down problems, thinking about design, and understanding why things work. Before you know it, you can generate code, but you can’t debug it… you can ship features, but you can’t explain them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp5rfpdef6r36tql5b792.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp5rfpdef6r36tql5b792.png" alt="AI vs Human thinking in software engineering" width="340" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AI should be your partner, not your brain’s replacement. So if you want your growth to flatline instantly, fully outsource your thinking to AI.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Avoiding Project Ownership
&lt;/h2&gt;

&lt;p&gt;There’s a reason people can write code for years and still be seen as “junior.” It’s not skill. It’s not intelligence. It’s ownership. Developers who grow take responsibility for outcomes, not just tasks. They speak up, form opinions, and challenge decisions respectfully. They propose solutions instead of waiting for instructions.&lt;/p&gt;

&lt;p&gt;But refusing ownership? That’s the fastest path to staying invisible. You become the person who “just does what they’re told,” and you get treated accordingly.&lt;/p&gt;

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

&lt;p&gt;So if your goal is to remain small forever, avoid ownership at all costs. If not, start taking responsibility.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Not Understanding the Business
&lt;/h2&gt;

&lt;p&gt;You don't get employed to write code, you get employed to create an impact &lt;em&gt;by&lt;/em&gt; writing code. Engineers who grow fast understand one thing: the business drives everything. Who are we building this for? What problem does it solve? Why does it matter? How does it affect revenue, users, cost, performance, or experience?&lt;/p&gt;

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

&lt;p&gt;Once you understand why something matters, your decisions get sharper, your communication gets clearer, and your contributions get noticed. Seniority is basically the ability to connect code to outcomes.&lt;/p&gt;

&lt;p&gt;On the other hand, if you want to remain easily replaceable, focus only on the code and ignore everything else.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Never Reflecting or Asking the Hard Questions
&lt;/h2&gt;

&lt;p&gt;You cannot improve if you never pause to see where you are, where you want to go, and what you need to get there. Many developers go year after year without reflecting on what worked, what didn’t, and what they could do differently. Reflection is what turns experience into wisdom. Without it, you’re just moving in circles, accumulating years, but not skills.&lt;/p&gt;

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

&lt;p&gt;Reflection forces you to confront your blind spots, the bugs in your mindset and workflow that no tutorial can fix. It’s uncomfortable, but discomfort is where growth actually lives. So, that being said, if you want to flatline indefinitely, never reflect on your growth.&lt;/p&gt;

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

&lt;p&gt;Growth is about thinking, creating, leading, and connecting. It’s about tackling uncomfortable challenges, building real projects, practicing consistently, communicating clearly, understanding the business, and taking ownership of your impact. Ignore any of these, and you’ll never move forward. Follow them, and even in a year, you’ll look back and be amazed at how far you’ve come. If you think coding harder alone will make you climb up the ranks? Think again.&lt;/p&gt;

&lt;p&gt;If you’ve made it this far, ask yourself: are you doing these things, or are you doing what’s easy? Because the difference between being a &lt;strong&gt;“developer”&lt;/strong&gt; and being a &lt;strong&gt;“developer who grows”&lt;/strong&gt; comes down to the choices you make every day.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>careerdevelopment</category>
      <category>productivity</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Survive AI as a Programmer</title>
      <dc:creator>Christian Mbah</dc:creator>
      <pubDate>Mon, 01 Sep 2025 10:11:37 +0000</pubDate>
      <link>https://dev.to/chrismbah/how-to-survive-ai-as-a-programmer-5hp</link>
      <guid>https://dev.to/chrismbah/how-to-survive-ai-as-a-programmer-5hp</guid>
      <description>&lt;p&gt;As a software engineer you've probably wondered at least once about the impact of &lt;strong&gt;Artificial Intelligence (AI)&lt;/strong&gt; on your long-term career.&lt;/p&gt;

&lt;p&gt;Everywhere you look, AI tools are popping up that can write code, fix bugs, and even generate an entire app from scratch in seconds. &lt;/p&gt;

&lt;p&gt;At first, it feels cool seeing how much artificial intelligence is growing and how much better it helps you solve coding tasks, but then the bigger question creeps in: if AI keeps getting better, will it eventually replace me in the long run?&lt;/p&gt;

&lt;h2&gt;
  
  
  Will AI replace software engineers?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Well, yes and no.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI is already replacing some software engineers and that trend isn’t slowing down, but it &lt;strong&gt;won’t&lt;/strong&gt; replace all of us. That’s the part worth paying attention to and we’ll get into &lt;em&gt;why&lt;/em&gt; in a moment, but first let’s acknowledge the obvious: this shift isn’t shocking. &lt;/p&gt;

&lt;p&gt;As engineers, we’ve always built tools to replace old ways of working. This is just another wave of disruption, only now we’re the ones in the hot seat. Ironic, isn’t it? Building our own replacement.&lt;/p&gt;

&lt;p&gt;And if you think about it, this isn’t a new story. We build new things to improve or replace the old. Spotify reshaped the music industry, Netflix transformed how we watch movies, and Uber changed the way we think about taxis.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8suekdjfp5fiaoyhfqyo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8suekdjfp5fiaoyhfqyo.png" alt="Netflix, Uber and other main stream apps" width="799" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But here’s the good news: those older industries didn’t completely disappear. I still went to the cinema last week, taxi drivers migrated to Uber, and people still buy songs. The world changed, but it didn’t end, and the same will be true for software engineering.&lt;/p&gt;

&lt;p&gt;Which brings us to the real question: how do you survive, adapt, and stay valuable as a software engineer in the age of AI?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Engineer Who Stands Out
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Fact: Artificial Intelligence can code like crazy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You already know this so let's build on it. If AI can code, why not think beyond coding, broaden your perspective and use your technical skills together with knowledge from other fields to create real impact. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let's take a case study of 2 software engineers:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Software Engineer 1:&lt;/strong&gt; Can code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Software Engineer 2:&lt;/strong&gt; Can code, but doesn't stop there. He's built range in multiple domains like product management, design, marketing, sales, or business strategy.&lt;/p&gt;

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

&lt;p&gt;Now picture this: both engineers are asked to build a feature for an e-commerce app.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Engineer 1&lt;/strong&gt; delivers clean, working code. The feature is technically solid, but that’s about it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Engineer 2&lt;/strong&gt; also writes the code, but because they understand product and user experience, they suggest a small tweak to improve checkout speed. Thanks to their grasp of business strategy, they highlight how this tweak could increase conversions. And with their communication skills, they explain the impact clearly to both the design and business teams.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both wrote code. But only one created impact. And that’s the engineer AI can’t easily replace.&lt;/p&gt;

&lt;p&gt;So if AI is already good at coding, which of these two engineers do you think will stand out in the long run? Exactly, the second one. The guy who connects technical skills with multiple domains and consistently drives outcomes that actually matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Edge Engineer 2 Has Over AI
&lt;/h2&gt;

&lt;p&gt;AI is insanely good at narrow, well-defined tasks. Ask it to optimize a query, generate boilerplate code, or refactor a function and it’ll crush it every time. But here’s the catch: AI doesn’t do well once you step outside of those boundaries. It can remix existing patterns, but it struggles to combine ideas from different domains to create something new.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engineer 2’s&lt;/strong&gt; edge is exactly that: they don’t just code, they think. They pull from product, design, business, and even psychology to build things that actually matter. They understand customer pain points, connect dots across fields, and create value AI can’t see because it’s trained on the average of what’s &lt;em&gt;already been done&lt;/em&gt;.&lt;/p&gt;

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

&lt;p&gt;The truth is, impact comes from &lt;em&gt;originality&lt;/em&gt; and &lt;em&gt;empathy&lt;/em&gt;, two areas where humans still have the upper hand. AI can code. &lt;strong&gt;Engineer 2&lt;/strong&gt; can create outcomes that change the game.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Become Engineer 2
&lt;/h2&gt;

&lt;p&gt;Becoming Engineer 2 means you stop being defined only by your ability to code and start stacking skills that make you indispensable. Here’s how:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Strengthen Your Core Technical Depth&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI can write code, but it doesn’t truly understand systems. Your technical foundation should be unshakable; architecture, scalability, debugging, and performance optimization are areas where depth matters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Learn to Think Like a Product Manager&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Understand why features are built, what problems they solve, and how they tie into business goals. Engineers who think beyond their tickets have a strategic edge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Adopt Design Thinking&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You don’t need to be a designer, but knowing the principles of UX, UI, and user research will make your work far more impactful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Understand Business and Growth&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Learn how companies make money, how products are sold, and what drives revenue. Engineers with business insight become trusted decision-makers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Invest in Soft Skills&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Communication, persuasion, and empathy are career multipliers. They determine how much influence you can have, no matter your technical strength.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Master AI Instead of Fearing It&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Learn how AI works, where it shines, and where it fails. Engineers who can use AI effectively will outperform those who ignore it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Collaborate Across Functions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Spend time with teams outside engineering like marketing, sales, design, operations. This is how you connect technical skill with real-world impact.&lt;/p&gt;

&lt;p&gt;Engineer 2’s advantage isn’t just their skills; it’s how they approach problems. The &lt;em&gt;multi-spired&lt;/em&gt; engineer doesn’t see themselves as “just a programmer”; they see themselves as a builder of value. And that mindset is what separates those who succeed in an AI-driven world from those who get left behind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Having a Future-Proof Mindset
&lt;/h2&gt;

&lt;p&gt;The engineers who stay relevant in the age of AI aren’t the ones who cling to what they already know, they’re the ones who stay curious and adaptable. &lt;/p&gt;

&lt;p&gt;Curiosity is your edge. Keep exploring new tools, frameworks, and concepts, and never settle for just “doing your job.” Look past tickets and deadlines and learn the bigger picture: what your product does, who it serves, and why it matters.&lt;/p&gt;

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

&lt;p&gt;The tech world will always shift, and those who grow with it will stay valuable. Sharpen your communication and leadership skills because engineers who can guide, influence, and connect ideas are rare. Stop seeing yourself as “just a programmer.” Start seeing yourself as a builder of real value.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Road Ahead
&lt;/h2&gt;

&lt;p&gt;AI will write more code than any single engineer ever could and there's nothing we can do about it. But code alone &lt;strong&gt;does not&lt;/strong&gt; create value. The software engineers who succeed will be the ones who decide what to build and why it matters.&lt;/p&gt;

&lt;p&gt;Don’t wait for layoffs or industry disruptions to force you into change. Start now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Learn a skill outside engineering.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Shadow a different team.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Take on a project that challenges you.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The future belongs to engineers who can see beyond the code. Stack your skills, connect the dots across disciplines, and become the person no tool can fully replace.&lt;/p&gt;

</description>
      <category>openai</category>
      <category>ai</category>
      <category>softwareengineering</category>
      <category>chatgpt</category>
    </item>
    <item>
      <title>Dev, Staging, and Production Environments in Software Development</title>
      <dc:creator>Christian Mbah</dc:creator>
      <pubDate>Sat, 23 Aug 2025 10:49:38 +0000</pubDate>
      <link>https://dev.to/chrismbah/dev-staging-and-production-environments-what-they-mean-in-software-development-90a</link>
      <guid>https://dev.to/chrismbah/dev-staging-and-production-environments-what-they-mean-in-software-development-90a</guid>
      <description>&lt;p&gt;Every software product always goes through multiple processes before it’s ready for real users. One of the most important of these processes is testing and validating the code in different environments.&lt;/p&gt;

&lt;p&gt;Instead of writing code on your computer and immediately releasing it to the world (which would be risky), software engineers use a structured flow: first &lt;strong&gt;development&lt;/strong&gt;, then &lt;strong&gt;staging&lt;/strong&gt;, and finally &lt;strong&gt;production&lt;/strong&gt;. Each of these environments serves a unique purpose, helping teams catch bugs that were missed, improve performance, and essentially ensures the final product is reliable for users.&lt;/p&gt;

&lt;p&gt;Think of it like you're a musician preparing for a big performance:&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;The development environment is where musicians practice individually&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;The staging environment is the rehearsal with the whole band where they go through their performance and how good they sound together.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;The production environment is the live concert, with the audience watching.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Now we've gotten all that cleared up, let's talk in detail about each of these stages, how they differ and how important each of them are in building a solid software product.&lt;/p&gt;

&lt;h2&gt;
  
  
  Development environment
&lt;/h2&gt;

&lt;p&gt;This is where all the building and experimenting happens and it's usually set up in your computer. It’s the space where your code is written and initially tested before it’s seen by anyone outside the team.&lt;/p&gt;

&lt;p&gt;Here, developers have the freedom to try out new features, fix bugs, or make changes without worrying about breaking the actual application that users depend on. It’s usually connected to a local database or dummy data so that testing doesn’t interfere with real information.&lt;/p&gt;

&lt;p&gt;The main players of this stage are the &lt;strong&gt;software developers&lt;/strong&gt; themselves.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Staging environment
&lt;/h2&gt;

&lt;p&gt;Once you’ve got your code working in development, the next stop is the staging environment and you can think of this as your _“final rehearsal” _ before going live.&lt;/p&gt;

&lt;p&gt;In staging, your app runs on a server that’s set up to be as close as possible to production. This means it uses almost the same configuration, services, and dependencies that your real users will eventually rely on but since it’s still a safe space, if something breaks here, it won’t affect actual customers.&lt;/p&gt;

&lt;p&gt;The main players of this stage are the &lt;strong&gt;Quality Assurance (QA) testers&lt;/strong&gt;. They’re the ones stress-testing your work, hunting bugs, and making sure it’s polished before it goes live (sometimes a bit of a headache for us developers 😅)&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Production environment
&lt;/h2&gt;

&lt;p&gt;This is it, the main event. In this environment, your app finally goes live and real users interact with it. Everything that happens here matters because it’s tied to actual customers, real data, and in many cases, real money.&lt;/p&gt;

&lt;p&gt;Unlike development or staging, production isn’t very forgiving. If something breaks here, your users will notice, and that can mean frustrated customers, lost revenue, or even security issues. That’s why teams are extra careful about what gets deployed into production.&lt;/p&gt;

&lt;p&gt;In this environment, you’ll see practices like &lt;strong&gt;gradual rollouts&lt;/strong&gt; (where updates are released to a small group of users first), &lt;strong&gt;blue-green deployments&lt;/strong&gt;, or &lt;strong&gt;canary releases&lt;/strong&gt;. These strategies let you push updates with less risk, so if something goes wrong, you can roll it back before too many people are affected.&lt;/p&gt;

&lt;p&gt;Monitoring and security are also a huge deal here. You’ll want logging, alerts, and backup systems in place so you can react quickly if there’s ever a problem.&lt;/p&gt;

&lt;p&gt;The main players are the &lt;strong&gt;users&lt;/strong&gt; themselves. At this stage, it’s no longer about the developer or QA but giving your users the smoothest, most reliable experience possible.&lt;/p&gt;

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

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

&lt;p&gt;So, to sum it all up:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Development&lt;/strong&gt; is your playground where you build, test, and break things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Staging&lt;/strong&gt; is your dress rehearsal; the space to polish, demo, and catch problems before going live.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Production&lt;/strong&gt; is the big show, where your users are watching, and everything needs to run smoothly.&lt;/p&gt;

&lt;p&gt;Understanding these environments isn’t just for developers. It also helps product managers, designers, and even stakeholders appreciate the path from idea to a reliable product in users’ hands. At the end of the day, it's what keeps your software reliable, your team sane, and your users happy. &lt;/p&gt;

</description>
      <category>softwaredevelopment</category>
      <category>softwareengineering</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>What's the Difference between NPM and NPX</title>
      <dc:creator>Christian Mbah</dc:creator>
      <pubDate>Sat, 24 May 2025 17:22:21 +0000</pubDate>
      <link>https://dev.to/chrismbah/whats-the-difference-between-npm-and-npx-2eim</link>
      <guid>https://dev.to/chrismbah/whats-the-difference-between-npm-and-npx-2eim</guid>
      <description>&lt;p&gt;Every developer working with JavaScript has likely used one or both of these tools: &lt;strong&gt;NPM&lt;/strong&gt; and &lt;strong&gt;NPX&lt;/strong&gt;. But while they’re often used together, they serve very different purposes, and that can be confusing, especially for beginners. In fact, many developers use them without fully understanding what each one does or why they're using it.&lt;/p&gt;

&lt;p&gt;Let’s break it down in the simplest way possible.&lt;/p&gt;

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

&lt;p&gt;NPM stands for &lt;strong&gt;Node Package Manager&lt;/strong&gt;. It’s the default package manager for Node.js mainly used for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Installing packages (libraries, tools, etc.) into your project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Managing and updating dependencies in your &lt;code&gt;package.json&lt;/code&gt; file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Running scripts defined in &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

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

&lt;/div&gt;



&lt;p&gt;This command installs React and adds it to your &lt;code&gt;node_modules&lt;/code&gt; folder and &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;NPX&lt;/strong&gt; stands for &lt;strong&gt;Node Package eXecute&lt;/strong&gt;. It’s a tool that lets you run any package directly from the NPM registry, without needing to install it globally or keep it in your project.&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 shell"&gt;&lt;code&gt;npx create-react-app my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This runs the create-react-app command without requiring a global install. It temporarily downloads and executes it, then cleans up after itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use NPM vs NPX
&lt;/h2&gt;

&lt;p&gt;Use &lt;strong&gt;NPM&lt;/strong&gt; when you want to add a package to your project and manage it over time.&lt;/p&gt;

&lt;p&gt;Use &lt;strong&gt;NPX&lt;/strong&gt; when you want to run a tool or command temporarily, like a one-time script.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does It Matter?
&lt;/h2&gt;

&lt;p&gt;Knowing the difference helps you avoid cluttering your system with global installs and keeps your development environment cleaner.&lt;/p&gt;

&lt;p&gt;So if you're not sure whether to use npm or npx, ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do I need this tool installed in my project permanently?&lt;/li&gt;
&lt;li&gt;If yes, use npm.&lt;/li&gt;
&lt;li&gt;If no, or just for a quick command, use npx.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>npm</category>
      <category>npx</category>
    </item>
    <item>
      <title>What Does Simple Addition Look Like in 10 Programming Languages?</title>
      <dc:creator>Christian Mbah</dc:creator>
      <pubDate>Sat, 10 May 2025 10:27:10 +0000</pubDate>
      <link>https://dev.to/chrismbah/what-does-simple-addition-look-like-in-10-programming-languages-2ed2</link>
      <guid>https://dev.to/chrismbah/what-does-simple-addition-look-like-in-10-programming-languages-2ed2</guid>
      <description>&lt;p&gt;When starting with a new programming language—whether through tutorials or courses—one of the first tasks we do is usually performing a basic calculation. It’s a simple but effective way to get familiar with the syntax and language rules.&lt;/p&gt;

&lt;p&gt;I got curious and decided to see how different languages handle basic calculation. Here, I’ll perform the simple addition operation “5 + 3” in 10 different programming languages, and the goal here is to explore how each language syntax differs in readability. I'll also note their compile and/or runtime and provide a rating out of 10 based on the readability of their syntax as well as list them in descending order.&lt;/p&gt;

&lt;p&gt;For consistency, I used the online coding platform &lt;a href="https://jdoodle.com" rel="noopener noreferrer"&gt;&lt;strong&gt;JDoodle&lt;/strong&gt;&lt;/a&gt;, so you can easily try out the examples yourself. Please note that the runtime is based on the JDoodle environment and doesn’t necessarily reflect how fast each language would run in a native or optimized environment. It just serves as a way to compare the languages in a controlled setup.&lt;/p&gt;

&lt;p&gt;Now that’s all cleared up, let's begin!&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;

&lt;span class="nf"&gt;print &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sum of x+y =&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Python makes it so easy: assign the values in variables &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;⁣, store the added values in variable ⁣&lt;code&gt;z&lt;/code&gt; and use the &lt;code&gt;print()&lt;/code&gt; function to display the result. It doesn’t get easier than this. Clean, simple, and easy to read.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Runtime:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;0.902 sec(s)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Rating:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;9.5&lt;/p&gt;

&lt;p&gt;To the surprise of no one, Python is at the top of the list. It’s simplicity and readability make it an ideal choice for beginners; it allows them to focus on learning without being overwhelmed by complex syntax.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: Some runtimes show "N/A" because of limitations in JDoodle's runtime environment.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;2. JavaScript&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript &lt;code&gt;console.log&lt;/code&gt; does the job here. It uses the &lt;code&gt;let&lt;/code&gt; keyword in assigning variables, stores the added value in a variable, and simply prints it out in the browser’s console. It’s simple, easy to read, versatile, and very useful for debugging.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Runtime&lt;/strong&gt;:
&lt;/h3&gt;

&lt;p&gt;N/A&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Rating&lt;/strong&gt;:
&lt;/h3&gt;

&lt;p&gt;9.0&lt;/p&gt;

&lt;p&gt;It's syntax is clean and straightforward, making it a popular choice for both beginners and experienced developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. C
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sum of x+y = %i"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&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;C requires a bit more setup compared to Python and JavaScript, but that’s what makes learning low-level languages important. It helps you understand the mechanics of memory management and how operations work at a deeper level.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Runtime:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;1.132 sec(s)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Rating:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;8.0/10&lt;/p&gt;

&lt;p&gt;C provides more control over system resources but requires more boilerplate code, making it less beginner-friendly for simple tasks like addition.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. PHP
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

    &lt;span class="nv"&gt;$x&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="nv"&gt;$y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nv"&gt;$z&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nv"&gt;$y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nv"&gt;$msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Sum of x+y = '&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$msg&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$z&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PHP is a widely used scripting language designed for web development. It’s simple, user-friendly, and readable, especially when dealing with basic operations. While PHP may not be as fast or strict as some compiled languages, it's great for web scripting and server-side applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Runtime:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;N/A&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Rating:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;7.5/10&lt;/p&gt;

&lt;p&gt;The syntax is simple and straightforward but could be more structured and robust for larger, more complex applications&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Go
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
    &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
    &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sum of x + y = %d"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&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;Go’s syntax is very straightforward and is designed for efficiency and scalability, especially in concurrent programming.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Runtime:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;N/A&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Rating:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;7.0/10&lt;/p&gt;

&lt;p&gt;Although the syntax is simple and effective for concurrent and scalable programming, the extra imports and verbosity for output reduce its overall simplicity compared to the previous languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. C++
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;cout&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s"&gt;"Sum of x+y = "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;z&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;C++ syntax is relatively clear, but it requires more boilerplate than languages like Python or JavaScript. The need for header files and the use of &lt;code&gt;cout&lt;/code&gt; for output might make the code feel a bit more complex, though it allows for greater control over performance and memory management.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Runtime:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;1.052 sec(s)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Rating:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;6.8/10&lt;/p&gt;

&lt;p&gt;The syntax is straightforward but adds verbosity with its use of header files and manual output handling. While powerful, it may feel complex for beginners looking for quick and simple calculations.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. C
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sum of x + y = "&lt;/span&gt;&lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;z&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;C# follows a structured approach, but the need for defining a class and using specific methods such as &lt;code&gt;Console.Write&lt;/code&gt; makes it more verbose compared to higher-level languages. The syntax is clear, but it’s less beginner-friendly and involves more boilerplate code for a simple task.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Runtime:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;12.075 sec(s)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Rating:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;6.5/10&lt;/p&gt;

&lt;p&gt;Although the code is easy to read, it introduces more complexity due to the necessity of class structures and method calls. The added boilerplate reduces the efficiency for a simple calculation.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Java
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Java requires defining a full class structure, which feels excessive for a simple calculation. Its strict syntax ensures reliability and performance but adds complexity, making it less intuitive for beginners.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Runtime:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;1.402 sec(s)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Rating:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;6.0/10&lt;/p&gt;

&lt;p&gt;The need for a class structure and the strict syntax makes Java feel cumbersome for a simple task like addition, although it’s powerful and efficient once you get familiar.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Objective-C
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight objective_c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#import &amp;lt;Foundation/Foundation.h&amp;gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;NSAutoreleasePool&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;NSAutoreleasePool&lt;/span&gt; &lt;span class="nf"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;NSLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;@"Sum of x + y = %i"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;pool&lt;/span&gt; &lt;span class="nf"&gt;drain&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Objective-C adds object-oriented features to C, but the syntax is much more verbose, especially for simple tasks like addition. It’s powerful but requires more boilerplate code that isn’t easily readable, making it less beginner-friendly compared to other languages like C++ or even Java.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Runtime:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;7.846 sec(s)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Rating:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;5.5/10&lt;/p&gt;

&lt;p&gt;The verbose syntax and additional boilerplate make it harder to write and understand for simple tasks, though it is still powerful and flexible for complex applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Assembly
&lt;/h2&gt;



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

global _start

_start:

    mov     eax, [x]
    sub     eax, '0'
    mov     ebx, [y]
    sub     ebx, '0'
    add     eax, ebx
    add     eax, '0'

    mov     [sum], eax

    mov     ecx, msg
    mov     edx, len
    mov     ebx, 1
    mov     eax, 4
    int     0x80

    mov     ecx, sum
    mov     edx, 1
    mov     ebx, 1
    mov     eax, 4
    int     0x80

    mov     eax, 1
    int     0x80

section .data
    x db '5'
    y db '3'
    msg db  "sum of x and y is "
    len equ $ - msg

segment .bss

    sum resb 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Assembly language is extremely low-level and requires extensive code even for simple operations like addition. Although it offers maximum control over system hardware and performance, the complexity and verbosity make it unsuitable for simple tasks and less beginner-friendly than higher-level languages.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Runtime:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;0.876 sec(s)&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Rating:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;4.0/10&lt;/p&gt;

&lt;p&gt;It’s no surprise that this gets last place. It’s too verbose, prone to errors, and &lt;em&gt;definitely&lt;/em&gt; not practical for simple tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Reflection&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I find it interesting how something as simple as adding two numbers can be expressed in so many different ways. But one thing that’s certain is that although each language has its own unique syntax and rules, they all ultimately achieve the same result. Some languages may have simpler syntax, while others are more complex, but at the end of the day, each of them has their strengths and weaknesses, and they’re all just tools for solving problems.&lt;/p&gt;

&lt;p&gt;So which of these languages do you prefer for simple tasks? Feel free to share your thoughts!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>python</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Build a simple REST API with Node, Express and MongoDB</title>
      <dc:creator>Christian Mbah</dc:creator>
      <pubDate>Fri, 09 May 2025 11:30:49 +0000</pubDate>
      <link>https://dev.to/chrismbah/how-to-build-a-simple-rest-api-with-node-express-and-mongodb-2d4n</link>
      <guid>https://dev.to/chrismbah/how-to-build-a-simple-rest-api-with-node-express-and-mongodb-2d4n</guid>
      <description>&lt;p&gt;&lt;strong&gt;APIs&lt;/strong&gt; have always been an important component of modern technology. Whenever we interact with a computer or system to retrieve information or perform a function, Application Programming Interfaces &lt;strong&gt;(APIs)&lt;/strong&gt; are what help us communicate what we want to the system so it can understand&amp;nbsp;and&amp;nbsp;fulfill those requests. Among these, &lt;strong&gt;REST APIs&lt;/strong&gt; are a popular choice because they are simple to use and can handle a lot of different tasks.&lt;/p&gt;

&lt;p&gt;In this article we will be building a simple &lt;strong&gt;todo list&lt;/strong&gt; REST API for managing tasks using Express and MongoDB. You’ll cover everything from setting up your project to building the endpoints that handle CRUD (Create, Read, Update, Delete) operations, and by the end you’ll have the foundational skills to create your own APIs with Express and MongoDB.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you begin, ensure you have:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Node.js Installed:&lt;/strong&gt; Make sure Node.js is installed on your computer. You can download it from &lt;a href="https://nodejs.org" rel="noopener noreferrer"&gt;nodejs.org&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MongoDB Setup:&lt;/strong&gt; Either install MongoDB locally and access it with the GUI &lt;a href="https://www.mongodb.com/products/compass" rel="noopener noreferrer"&gt;MongoDB Compass&lt;/a&gt; or create a free account on &lt;a href="https://www.mongodb.com/cloud/atlas" rel="noopener noreferrer"&gt;MongoDB Atlas&lt;/a&gt; for a cloud-based database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;API Testing Tool:&lt;/strong&gt; Install &lt;strong&gt;Postman&lt;/strong&gt;, &lt;strong&gt;Insomnia,&lt;/strong&gt; or &lt;strong&gt;Thunder Client&lt;/strong&gt; to test the endpoints.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Setting Up Your Project
&lt;/h2&gt;

&lt;p&gt;Start by creating a folder with any name you like. For this guide, I’ll advise you to use &lt;code&gt;rest-api&lt;/code&gt; to keep things consistent. After that, open it in your preferred IDE. If you’re unsure, &lt;strong&gt;Visual Studio Code&lt;/strong&gt; is a great choice.&lt;/p&gt;

&lt;p&gt;Open the terminal in your VS Code or any IDE of your choice, navigate to the folder, and run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a &lt;code&gt;package.json&lt;/code&gt; file with default settings to manage your project dependencies.&lt;/p&gt;

&lt;p&gt;Next, install the following packages by running the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;express mongoose nodemon dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll be making use of the packages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;express&lt;/strong&gt;: For building the server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;mongoose&lt;/strong&gt;: To interact with MongoDB.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;nodemon&lt;/strong&gt;: For automatically restarting the server during development.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;dotenv:&lt;/strong&gt; To manage environment variables securely.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To make development easier and prevent manually restarting the server after every change, add a &lt;code&gt;start&lt;/code&gt; script in your &lt;code&gt;package.json&lt;/code&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="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;"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;"nodemon index.js"&lt;/span&gt;&lt;span class="w"&gt; 
 &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows you to start your server with the command &lt;code&gt;npm start&lt;/code&gt; . Your &lt;code&gt;package.json&lt;/code&gt; file should look like this:&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;"rest-api"&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;"1.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;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"index.js"&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;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"echo &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Error: no test specified&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; &amp;amp;&amp;amp; exit 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;"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;"nodemon index.js"&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;"keywords"&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;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"license"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ISC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"dotenv"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^16.4.7"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.21.2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"mongoose"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^8.9.4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"nodemon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^3.1.9"&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;
  
  
  &lt;strong&gt;Connecting to MongoDB&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Now that your project is all set up, the next step is to connect to your database, MongoDB.&lt;/p&gt;

&lt;p&gt;Start by creating a &lt;code&gt;.env&lt;/code&gt; file at the root of your folder. This is where you’ll store your MongoDB connection URI. This way, you can keep credentials safe and easily configurable.&lt;/p&gt;

&lt;p&gt;Inside the &lt;code&gt;.env&lt;/code&gt; file, store your connection URI in a variable, like this:&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="nv"&gt;MONGO_URI&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_mongodb_connection_string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using &lt;strong&gt;MongoDB Atlas&lt;/strong&gt;, you can get the connection string from your Atlas dashboard. For local MongoDB with &lt;strong&gt;MongoDB Compass&lt;/strong&gt;, it might look like this:&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="nv"&gt;MONGO_URI&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mongodb://localhost:27017/rest-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create a new file at the root of your project called &lt;code&gt;db.js&lt;/code&gt; to manage the MongoDB connection.&lt;/p&gt;

&lt;p&gt;Inside &lt;code&gt;db.js&lt;/code&gt;, add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// db.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Load environment variables&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connectDB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;MONGO_URI&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;MongoDB connected&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Catch error if connection fails&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error connecting to MongoDB:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;connectDB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a simple function for connecting your server to MongoDB with your connection URI.&lt;/p&gt;

&lt;p&gt;Now create a &lt;code&gt;index.js&lt;/code&gt; file that would be your main file. Then require and invoke the &lt;code&gt;connectDB&lt;/code&gt; function to establish a connection to your database.&lt;/p&gt;

&lt;p&gt;Example &lt;code&gt;index.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&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;connectDB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./db&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;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nf"&gt;connectDB&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Connect to database&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// Middleware to parse JSON requests&lt;/span&gt;

&lt;span class="c1"&gt;// Define a simple route&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello World!!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;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;`Server running on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the server with the command &lt;code&gt;npm run start&lt;/code&gt; in your terminal. If everything is set up correctly, you should see the message &lt;code&gt;MongoDB connected&lt;/code&gt; in the terminal.&lt;/p&gt;

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

&lt;p&gt;Well, congratulations! You just started your node server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Defining the data model
&lt;/h2&gt;

&lt;p&gt;The next step is to create a &lt;strong&gt;model&lt;/strong&gt; to define the structure of the data stored in MongoDB. For this tutorial, you’ll create a model for managing a collection of "tasks" in the to-do app.&lt;/p&gt;

&lt;p&gt;Inside your project create a &lt;code&gt;models&lt;/code&gt; folder to keep your models organized. Inside the &lt;code&gt;models&lt;/code&gt; folder, create a &lt;code&gt;Task.js&lt;/code&gt; file to define the schema.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define the Task Schema
&lt;/h2&gt;

&lt;p&gt;To define the model of each task, add the following code to &lt;code&gt;Task.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Define the Task schema&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TaskSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Title is required&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;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;completed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Create and export the Task model&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Task&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TaskSchema&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Explaining the schema fields
&lt;/h2&gt;

&lt;p&gt;To keep things simple, you’ll be using just a few fields in your schema, with each field having:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;title&lt;/strong&gt;: A required string field to store the task's title.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;description&lt;/strong&gt;: An optional string field to store additional details about the task.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;completed&lt;/strong&gt;: A boolean field indicating whether the task is done. By default, it’s set to &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this schema defined, you can now use the &lt;code&gt;Task&lt;/code&gt; model to interact with the &lt;code&gt;tasks&lt;/code&gt; collection in MongoDB.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Building the API Endpoints&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The next step is to &lt;strong&gt;create API endpoints&lt;/strong&gt; for handling CRUD operations in the todo app. These endpoints will allow you to interact with the &lt;code&gt;tasks&lt;/code&gt; collection in MongoDB through requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up routers
&lt;/h2&gt;

&lt;p&gt;The first step is to set up routers, which creates the routes that define endpoints. Create a folder named &lt;code&gt;routes&lt;/code&gt; and a file named &lt;code&gt;task.js&lt;/code&gt; inside it. Add the following code to your&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// routes/task.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&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;Task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../models/Task&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Import the Task schema&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Initialize the router&lt;/span&gt;

&lt;span class="c1"&gt;// Endpoints goes here&lt;/span&gt;

&lt;span class="c1"&gt;// Export the router for use in other files&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next step is to make your requests with the router.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Task
&lt;/h2&gt;

&lt;p&gt;Creating a task is done using a &lt;strong&gt;POST request&lt;/strong&gt;, which is typically used to send data to the server to create a new resource.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Creating a new task&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;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s a quick explanation of the code:&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;router.post('/', ...)&lt;/code&gt; function that handles the &lt;code&gt;POST&lt;/code&gt; request sent to &lt;code&gt;/api/tasks&lt;/code&gt; You used &lt;code&gt;/&lt;/code&gt; here because the router will be mounted under &lt;code&gt;/api/tasks&lt;/code&gt; in the main app file.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;new Task(req.body)&lt;/code&gt; creates a new task instance using the data from the request’s body and &lt;code&gt;task.save()&lt;/code&gt; saves the task to the tasks collection in your database.&lt;/p&gt;

&lt;p&gt;If successful, the server responds with a status code &lt;code&gt;201&lt;/code&gt; (Created) and the saved task data, but if there’s an error, a &lt;code&gt;500&lt;/code&gt; status code is sent with an error message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fetching Tasks
&lt;/h2&gt;

&lt;p&gt;The next endpoint you’ll implement allows the client to fetch a list of all tasks stored in the database. This is done using a &lt;strong&gt;GET request&lt;/strong&gt;, which is typically used to fetch data from the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Get all tasks&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tasks&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;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Fetch all tasks from the database&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;tasks&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// Return the list of tasks&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To retrieve tasks, the &lt;code&gt;router.get('/', ...)&lt;/code&gt; function is used to handle &lt;strong&gt;GET requests&lt;/strong&gt; sent to &lt;code&gt;/api/tasks&lt;/code&gt;. This endpoint will fetch all tasks from the database using the &lt;code&gt;Task.find()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Once all the tasks are retrieved, the server responds with a status code &lt;code&gt;200&lt;/code&gt; and sends the tasks in JSON format. If an error occurs during this process, the server responds with a &lt;code&gt;500&lt;/code&gt; status code and an error message to help diagnose the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Updating a Task
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;PUT&lt;/strong&gt; request allows you to update an existing task in the database. You’ll handle this by using the task's &lt;code&gt;ID&lt;/code&gt;⁣ to locate it, and then you’ll update the fields that are passed in the request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Update a task&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;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;completed&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Extract the task ID from the URL&lt;/span&gt;

    &lt;span class="c1"&gt;// Find the task by ID and update it&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updatedTask&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;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByIdAndUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;completed&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;new&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Return the updated task&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// If no task is found, return an error&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;updatedTask&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Task not found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Respond with the updated task&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;updatedTask&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, the &lt;code&gt;router.put('/:id', ...)&lt;/code&gt; function handles &lt;strong&gt;PUT requests&lt;/strong&gt; sent to &lt;code&gt;/api/tasks/:id&lt;/code&gt;, where &lt;code&gt;:id&lt;/code&gt; is a placeholder for the task’s unique identifier. This endpoint is responsible for updating an existing task with the specified ID.&lt;/p&gt;

&lt;p&gt;The new task data is extracted from &lt;code&gt;req.body&lt;/code&gt;, while &lt;code&gt;req.params.id&lt;/code&gt; contains the ID of the task to be updated. Using &lt;code&gt;Task.findByIdAndUpdate(id, updateData, options)&lt;/code&gt;, the task is located and updated with the provided data. The &lt;code&gt;{ new: true }&lt;/code&gt; option ensures that the updated task is returned in the response.&lt;/p&gt;

&lt;p&gt;If the task with the specified ID isn’t found, the server responds with a &lt;code&gt;404&lt;/code&gt; status and a message indicating that the task doesn’t exist. For any other errors, a &lt;code&gt;500&lt;/code&gt; status is sent along with the error message to help debug the issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deleting a Task
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;DELETE&lt;/strong&gt; request allows you to delete a specific task from the database using its &lt;code&gt;ID&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Delete a task&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Extract the task ID from the URL&lt;/span&gt;
    &lt;span class="c1"&gt;// Find and delete the task by ID&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deletedTask&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;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByIdAndDelete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// If no task is found, return an error message&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;deletedTask&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Task not found&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Task deleted successfully&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="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;router.delete('/:id', ...)&lt;/code&gt; function handles &lt;strong&gt;DELETE requests&lt;/strong&gt; sent to &lt;code&gt;/api/tasks/:id&lt;/code&gt;, where &lt;code&gt;:id&lt;/code&gt; represents the unique identifier of the task to be deleted. This endpoint is designed to remove a specific task from the database.&lt;/p&gt;

&lt;p&gt;The task ID is extracted from the URL using &lt;code&gt;req.params.id&lt;/code&gt;. The &lt;code&gt;Task.findByIdAndDelete(id)&lt;/code&gt; method is then used to find and delete the task with the specified ID. If the task doesn’t exist, the server responds with a &lt;code&gt;404&lt;/code&gt; status and a message indicating that the task couldn’t be found.&lt;/p&gt;

&lt;p&gt;After the task has been deleted, the server returns a &lt;code&gt;200&lt;/code&gt; status along with a success message. In case of any errors during this process, the server catches the error and responds with a &lt;code&gt;500&lt;/code&gt; status and the corresponding message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In summary, your &lt;code&gt;routes/tasks.js&lt;/code&gt; file should finally look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// routes/task.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;express&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;Task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../models/Task&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Import the Task schema&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Router&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Initialize the router&lt;/span&gt;

&lt;span class="c1"&gt;// Creating a new task&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;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Get all tasks&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;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tasks&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;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Fetch all tasks from the database&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;tasks&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="c1"&gt;// Return the list of tasks&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Update a task&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;put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;completed&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Extract the task ID from the URL&lt;/span&gt;

    &lt;span class="c1"&gt;// Find the task by ID and update it&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updatedTask&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;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByIdAndUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;completed&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;new&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Return the updated task&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// If no task is found, return an error&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;updatedTask&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Task not found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Respond with the updated task&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;updatedTask&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Delete a task&lt;/span&gt;
&lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/:id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Extract the task ID from the URL&lt;/span&gt;
    &lt;span class="c1"&gt;// Find and delete the task by ID&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deletedTask&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;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findByIdAndDelete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// If no task is found, return an error message&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;deletedTask&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Task not found&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="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Task deleted successfully&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="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Export the router for use in other files&lt;/span&gt;
&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;router&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don’t forget to call your router in your &lt;code&gt;index.js&lt;/code&gt; file after creating the endpoints&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tasksRouter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./routes/tasks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Using the tasks router&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/tasks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tasksRouter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, your folder structure should look a lot like this:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Testing the Endpoints
&lt;/h2&gt;

&lt;p&gt;You can use tools like &lt;strong&gt;Postman&lt;/strong&gt;, &lt;strong&gt;Thunder Client&lt;/strong&gt;, or any API testing tool to test the endpoints.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Creating a Task&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTTP Method&lt;/strong&gt;: &lt;code&gt;POST&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;URL&lt;/strong&gt;: &lt;code&gt;http://localhost:5000/api/tasks&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Body&lt;/strong&gt;: Add a JSON body with the task data:&lt;br&gt;
&lt;/p&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;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Buy groceries"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Milk, bread, and eggs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"completed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&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;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expected Result&lt;/strong&gt;: The response should include the newly created task with a status code of &lt;code&gt;201&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Get All Tasks&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTTP Method&lt;/strong&gt;: &lt;code&gt;GET&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;URL&lt;/strong&gt;: &lt;code&gt;http://localhost:5000/api/tasks&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expected Result&lt;/strong&gt;: The response should include a list of all tasks. If there are no tasks, you’ll see an empty array (&lt;code&gt;[]&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. Update a Task&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTTP Method&lt;/strong&gt;: &lt;code&gt;PUT&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;URL&lt;/strong&gt;: &lt;code&gt;http://localhost:5000/api/tasks/:id&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;(Replace&lt;/em&gt; &lt;code&gt;:id&lt;/code&gt; with the actual ID of the task you want to update.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Body&lt;/strong&gt;: Add the updated task data in the JSON format:&lt;br&gt;
&lt;/p&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;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Updated Task Title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Updated task description"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"completed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expected Result&lt;/strong&gt;: The response should include the updated task with a status code of &lt;code&gt;200&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Delete a Task&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;HTTP Method&lt;/strong&gt;: &lt;code&gt;DELETE&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;URL&lt;/strong&gt;: &lt;code&gt;http://localhost:5000/api/tasks/:id&lt;/code&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;(Replace&lt;/em&gt; &lt;code&gt;:id&lt;/code&gt; with the actual ID of the task you want to delete.)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Expected Result&lt;/strong&gt;: A confirmation message such as:&lt;br&gt;
&lt;/p&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;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Task deleted successfully"&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;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These tests make sure that your endpoints are functioning as expected. If any test fails, check your code for errors, validate the data, and ensure your server and MongoDB are running correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finalizing the Project
&lt;/h2&gt;

&lt;p&gt;To prepare your project to be scalable and maintainable, it’s best to structure it into distinct folders such as &lt;code&gt;routes/&lt;/code&gt;⁣, &lt;code&gt;models/&lt;/code&gt; and &lt;code&gt;config/&lt;/code&gt;⁣. Also make sure you store sensitive information like the database URI and API keys in a &lt;code&gt;.env&lt;/code&gt; file and use the &lt;code&gt;dotenv&lt;/code&gt; package to access them in your code.&lt;/p&gt;

&lt;p&gt;For deployment, you can host your server on platforms like &lt;a href="https://www.heroku.com/" rel="noopener noreferrer"&gt;Heroku&lt;/a&gt; and &lt;a href="https://vercel.com/" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;. Both platforms offer free tiers, making it easy to deploy your REST API.&lt;/p&gt;

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

&lt;p&gt;To sum it up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You learned how to create a simple REST API using Express and MongoDB, implementing the fundamental CRUD operations (Create, Read, Update, Delete).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You also saw how to set up and structure your project to keep it clean and scalable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You’ve also tested your API with Postman or Thunder Client.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this, you can now start building your own REST APIs and even expand it further by adding more features, such as authentication or proper data validation when making requests.&lt;/p&gt;

</description>
      <category>node</category>
      <category>express</category>
      <category>mongodb</category>
      <category>webdev</category>
    </item>
    <item>
      <title>6 Best Practices in Software Engineering</title>
      <dc:creator>Christian Mbah</dc:creator>
      <pubDate>Thu, 08 May 2025 08:53:42 +0000</pubDate>
      <link>https://dev.to/chrismbah/6-best-practices-in-software-engineering-2io6</link>
      <guid>https://dev.to/chrismbah/6-best-practices-in-software-engineering-2io6</guid>
      <description>&lt;p&gt;Best practices are a &lt;strong&gt;set of guidelines, ethics, or ideas&lt;/strong&gt; that represent the most effective or safest method of achieving a business function. It is a method or technique that has been broadly accepted as superior to others in its category due to the fact that it has a tendency to produce superior results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices in Software Engineering
&lt;/h2&gt;

&lt;p&gt;Best practices in software engineering are established guidelines and principles that help teams create high-quality, maintainable, and effective software products with fewer errors and rework. They offer a template for organizing workflows, improving collaboration, and delivering reliable software that meets user and business needs.&lt;/p&gt;

&lt;p&gt;The importance of best practices in software engineering is in their ability to improve code quality, reduce bugs, improve security, and save time and costs over the project lifecycle. I’ve created a list of best practices every software engineer should adhere to, and by following these practices, teams can create adaptable and scalable software that remains relevant amid changing technologies and requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. DRY principle
&lt;/h2&gt;

&lt;p&gt;The DRY principle — "Don't Repeat Yourself" — is simply not being redundant in your code. Instead of duplicating logic in multiple places throughout your codebase, you want to write reusable components: functions, classes, or modules that can be reused wherever they are needed.&lt;/p&gt;

&lt;p&gt;By avoiding duplication, you reduce &lt;a href="https://en.wikipedia.org/wiki/Technical_debt" rel="noopener noreferrer"&gt;technical debt&lt;/a&gt; and the risk of inconsistencies or bugs when you must make modifications. When an item of logic needs changing, you only have to modify it in one place — and the improvement is reflected wherever it's used. The outcome is cleaner and more organized code that's easier to read, test, and debug.&lt;/p&gt;

&lt;p&gt;DRY can be achieved through &lt;strong&gt;abstraction&lt;/strong&gt; — identifying repeated patterns and turning them into reusable building blocks. When applied consistently, it speeds up development, promotes consistency, and makes it easier for teams to collaborate, since the codebase becomes more organized and predictable.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. KISS principle
&lt;/h2&gt;

&lt;p&gt;This stands for “Keep It Simple, Stupid” and it emphasizes simplicity in design and code, avoiding over-engineering, and focusing on clear, maintainable, and efficient solutions. In software engineering, it’s easy to overthink a solution — adding multiple layers of logic, edge case handling, and abstractions that aren’t immediately needed. While it might feel like you’re future-proofing your code, most times you’re just making it harder to understand, test, and maintain.&lt;/p&gt;

&lt;p&gt;Keeping things simple means solving the problem at hand with the &lt;strong&gt;most straightforward, readable solution possible&lt;/strong&gt;. It doesn’t mean ignoring edge cases or scalability, but rather handling those when the need actually arises, not preemptively.&lt;/p&gt;

&lt;p&gt;Simple code is easier to debug, onboard into, and extend. Stick to what’s necessary — and nothing more.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. YAGNI principle
&lt;/h2&gt;

&lt;p&gt;YAGNI stands for “You Aren’t Gonna Need It,” and it’s a principle that encourages engineers to focus only on what’s necessary — not what &lt;em&gt;might&lt;/em&gt; be needed in the future. It opposes the temptation to overbuild features or add extra layers of functionality “just in case.”&lt;/p&gt;

&lt;p&gt;In practice, this means resisting the urge to anticipate every possible use case or future requirement. Even though it’s good to plan ahead, building for hypothetical scenarios could lead to bloated, complex codebases filled with unused logic and features. This not only wastes time but also increases the chances of introducing bugs and confusion.&lt;/p&gt;

&lt;p&gt;By following the YAGNI principle, developers stay focused on implementing actual, verified requirements — functionality that is needed now, not later. It encourages shipping lean, working software sooner and iterating based on actual user feedback rather than speculation. It also allows for better maintainability and makes the code easier to refactor or scale when real needs are clear.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Testing
&lt;/h2&gt;

&lt;p&gt;Testing is a non-negotiable part of software development. It makes sure your code does what it’s supposed to do — not just in best-case scenarios, but under real-world conditions too.&lt;/p&gt;

&lt;p&gt;Good tests basically act like a safety net. They catch bugs early, prevent regressions, and give you peace of mind when refactoring or adding new features. Without tests, even small changes can be unpredictable and risky.&lt;/p&gt;

&lt;p&gt;There are different types of testing — unit tests for individual functions, integration tests for how parts of the system work together, and end-to-end tests that simulate actual user interactions. While not every line of code needs a test, the goal is to cover the parts that are critical to functionality and prone to change.&lt;/p&gt;

&lt;p&gt;Testing your code not only improves your software — it also allows better collaboration. If tests exist, new developers can confidently make changes without worrying they're breaking something that already works.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Design before Coding
&lt;/h2&gt;

&lt;p&gt;Jumping straight into code might feel productive, but without a clear plan, you’re simply setting yourself up for rework and confusion down the line. “Design before coding” simply means thinking through your solution before you start typing.&lt;/p&gt;

&lt;p&gt;But this doesn’t always mean drawing detailed &lt;a href="https://www.geeksforgeeks.org/unified-modeling-language-uml-introduction/" rel="noopener noreferrer"&gt;UML diagrams&lt;/a&gt; or writing pages of documentation. It can be as simple as sketching out a flow, defining data models, or breaking a problem into smaller parts. The goal is to clarify &lt;em&gt;what&lt;/em&gt; you’re building and &lt;em&gt;how&lt;/em&gt; the pieces fit together — before you start implementing.&lt;/p&gt;

&lt;p&gt;Whether you’re building a feature, designing an API, or structuring a system, taking time to plan before you build leads to better outcomes — for both your code and your team.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Code Reviews
&lt;/h2&gt;

&lt;p&gt;Code reviews are more than just a quality check —they’re a collaborative process that helps teams grow, catch issues early, and maintain a consistent codebase.&lt;/p&gt;

&lt;p&gt;A good review isn’t just about pointing out bugs or nitpicking syntax. It’s about understanding the intent behind the code, offering constructive feedback, and suggesting improvements that make the code cleaner, more efficient, or easier to understand. It’s also an opportunity to learn from each other — whether it's discovering a new pattern, a better naming convention, or a smarter approach.&lt;/p&gt;

&lt;p&gt;Code review avoids bottlenecks, reduces technical debt, and makes sure the code is consistent with team standards. It also spreads knowledge across the team — when multiple people understand how a feature works, no one person becomes a single point of failure.&lt;/p&gt;

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

&lt;p&gt;Following best practices is not just about writing cleaner code; it’s about building a more efficient, collaborative, and future-ready development process. By incorporating these principles into your workflow, you’ll create software that’s not only high-quality but also easier to maintain, scale, and adapt as your projects grow.&lt;/p&gt;

&lt;p&gt;Adopting these best practices today will not only save you time but also set you up for long-term success, making sure you stay ahead in the tech industry.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>softwareengineering</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
