<?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: Manthan Ankolekar</title>
    <description>The latest articles on DEV Community by Manthan Ankolekar (@manthanank).</description>
    <link>https://dev.to/manthanank</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F583429%2Faa97b3f4-f9ee-457d-afbf-e728ecc4b491.png</url>
      <title>DEV Community: Manthan Ankolekar</title>
      <link>https://dev.to/manthanank</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/manthanank"/>
    <language>en</language>
    <item>
      <title>🚀 Deploying a Node.js Product API on Kubernetes with MongoDB</title>
      <dc:creator>Manthan Ankolekar</dc:creator>
      <pubDate>Thu, 18 Sep 2025 04:44:38 +0000</pubDate>
      <link>https://dev.to/manthanank/deploying-a-nodejs-product-api-on-kubernetes-with-mongodb-hfo</link>
      <guid>https://dev.to/manthanank/deploying-a-nodejs-product-api-on-kubernetes-with-mongodb-hfo</guid>
      <description>&lt;p&gt;Modern apps need to scale effortlessly while staying resilient. Kubernetes (K8s) has become the go-to platform for orchestrating containerized apps, ensuring scalability, self-healing, and portability.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll build and deploy a &lt;strong&gt;Node.js Product API&lt;/strong&gt; with MongoDB on Kubernetes. You’ll learn how to containerize the app, define Kubernetes manifests, and enable auto-scaling.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 What We’re Building
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;Node.js + Express REST API&lt;/strong&gt; with CRUD for products&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MongoDB database&lt;/strong&gt; with Mongoose ODM&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dockerized application&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kubernetes resources&lt;/strong&gt;: Deployment, Service, Ingress, Secrets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Horizontal Pod Autoscaler (HPA)&lt;/strong&gt; for auto-scaling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ingress Controller&lt;/strong&gt; for external access&lt;/li&gt;
&lt;/ul&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;Client → Ingress → Service → Pod(s) running Node.js API → MongoDB
                   ↑
                HPA scales pods dynamically
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📁 Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nodejs-kubernates/
├── src/
│   ├── config/db.js          # MongoDB connection
│   ├── controllers/          # Business logic
│   ├── models/product.model.js
│   ├── routes/product.routes.js
│   ├── middlewares/          # Error handling, validation
│   └── server.js             # Express entry point
├── k8s/
│   ├── deployment.yaml       # App Deployment
│   ├── service.yaml          # ClusterIP Service
│   ├── ingress.yaml          # Ingress (exposes API)
│   ├── secret.yaml           # MongoDB credentials
│   └── hpa.yaml              # Auto-scaling config
├── Dockerfile
├── docker-compose.yml        # Local dev
└── package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📝 Step 1 — Build the Node.js Product API
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Product&lt;/code&gt; schema:&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;productSchema&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;name&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="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;trim&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="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="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;price&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;Number&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="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;min&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;inStock&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;true&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="na"&gt;timestamps&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CRUD endpoints are exposed at &lt;code&gt;/api/products&lt;/code&gt;.&lt;br&gt;
Example request:&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 http://localhost:5000/api/products &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":"Laptop","price":999.99,"inStock":true}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📦 Step 2 — Containerize with Docker
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Dockerfile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:18-alpine&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci &lt;span class="nt"&gt;--only&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["node", "src/server.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build and run locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; nodejs-kubernates &lt;span class="nb"&gt;.&lt;/span&gt;
docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 5000:5000 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;MONGO_URI&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mongodb://host.docker.internal:27017/product-api &lt;span class="se"&gt;\&lt;/span&gt;
  nodejs-kubernates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ☸️ Step 3 — Kubernetes Manifests
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Deployment (&lt;code&gt;deployment.yaml&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-api&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-api&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-api&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-api&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;REGISTRY&amp;gt;/nodejs-kubernates:latest&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5000&lt;/span&gt;
          &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MONGO_URI&lt;/span&gt;
              &lt;span class="na"&gt;valueFrom&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;secretKeyRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app-secrets&lt;/span&gt;
                  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;MONGO_URI&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Service (&lt;code&gt;service.yaml&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-api-svc&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-api&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5000&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ClusterIP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ingress (&lt;code&gt;ingress.yaml&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networking.k8s.io/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Ingress&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-api-ingress&lt;/span&gt;
  &lt;span class="na"&gt;annotations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;kubernetes.io/ingress.class&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;alb&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;http&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
            &lt;span class="na"&gt;pathType&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Prefix&lt;/span&gt;
            &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-api-svc&lt;/span&gt;
                &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;number&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Secrets (&lt;code&gt;secret.yaml&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Secret&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app-secrets&lt;/span&gt;
&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Opaque&lt;/span&gt;
&lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;MONGO_URI&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;base64-encoded-uri&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Encode your Mongo URI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"mongodb://user:pass@host:27017/product-api"&lt;/span&gt; | &lt;span class="nb"&gt;base64&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  HPA (&lt;code&gt;hpa.yaml&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;autoscaling/v2&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HorizontalPodAutoscaler&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-api-hpa&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;scaleTargetRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
    &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;product-api&lt;/span&gt;
  &lt;span class="na"&gt;minReplicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;maxReplicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;
  &lt;span class="na"&gt;metrics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Resource&lt;/span&gt;
      &lt;span class="na"&gt;resource&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cpu&lt;/span&gt;
        &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Utilization&lt;/span&gt;
          &lt;span class="na"&gt;averageUtilization&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;70&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🚀 Step 4 — Deploy to Kubernetes
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Push your Docker image to a registry (DockerHub, AWS ECR, GCP Artifact Registry).&lt;/li&gt;
&lt;li&gt;Apply manifests:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; k8s/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check status:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods
kubectl get svc
kubectl get ingress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Access the API:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://&amp;lt;INGRESS-HOST&amp;gt;/api/products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📊 Step 5 — Scaling &amp;amp; Monitoring
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HPA&lt;/strong&gt; automatically scales pods between 2–10 based on CPU/memory usage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Liveness &amp;amp; Readiness probes&lt;/strong&gt; ensure only healthy pods receive traffic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logging &amp;amp; Monitoring&lt;/strong&gt;: Add Prometheus + Grafana, or pipe logs to ELK/CloudWatch.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔒 Production Considerations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;managed MongoDB&lt;/strong&gt; (Atlas, DocumentDB).&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;TLS/HTTPS&lt;/strong&gt; for ingress (cert-manager + Let’s Encrypt).&lt;/li&gt;
&lt;li&gt;Store secrets in &lt;strong&gt;Kubernetes Secrets or external vaults&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Define &lt;strong&gt;resource requests &amp;amp; limits&lt;/strong&gt; for predictable scaling.&lt;/li&gt;
&lt;li&gt;Add a &lt;strong&gt;CI/CD pipeline&lt;/strong&gt; to build, push, and deploy automatically.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;You’ve just deployed a &lt;strong&gt;Node.js Product API&lt;/strong&gt; on Kubernetes with:&lt;br&gt;
✅ Dockerized app&lt;br&gt;
✅ Kubernetes Deployment, Service &amp;amp; Ingress&lt;br&gt;
✅ Secrets for sensitive data&lt;br&gt;
✅ Auto-scaling with HPA&lt;/p&gt;

&lt;p&gt;This setup provides a strong foundation for microservices in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔗 GitHub Repository&lt;/strong&gt;: &lt;a href="https://github.com/manthanank/nodejs-kubernates" rel="noopener noreferrer"&gt;manthanank/nodejs-kubernates&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;🧑‍💻 Author&lt;/strong&gt;: &lt;a href="https://github.com/manthanank" rel="noopener noreferrer"&gt;Manthan Ankolekar&lt;/a&gt;&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>node</category>
      <category>aws</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>🚀 Deploying a Node.js CRUD App on AWS with Terraform</title>
      <dc:creator>Manthan Ankolekar</dc:creator>
      <pubDate>Tue, 16 Sep 2025 04:30:00 +0000</pubDate>
      <link>https://dev.to/manthanank/deploying-a-nodejs-crud-app-on-aws-with-terraform-50l3</link>
      <guid>https://dev.to/manthanank/deploying-a-nodejs-crud-app-on-aws-with-terraform-50l3</guid>
      <description>&lt;p&gt;Managing cloud infrastructure manually can quickly become messy. Terraform allows us to define infrastructure as code (IaC), making deployments &lt;strong&gt;repeatable, version-controlled, and automated&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll build a &lt;strong&gt;Node.js CRUD API&lt;/strong&gt; (with Express + MongoDB) and deploy it to &lt;strong&gt;AWS ECS Fargate&lt;/strong&gt; using &lt;strong&gt;Terraform&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧩 What We’re Building
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;RESTful Todo API&lt;/strong&gt; (CRUD endpoints with Express + MongoDB).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dockerized app&lt;/strong&gt; pushed to &lt;strong&gt;Amazon ECR&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS ECS Fargate service&lt;/strong&gt; running containers in a managed VPC.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application Load Balancer (ALB)&lt;/strong&gt; to expose the service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets Manager&lt;/strong&gt; for storing MongoDB credentials securely.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch Logs&lt;/strong&gt; for centralized logging.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s the final architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Client → ALB → ECS (Fargate Task) → MongoDB (Atlas/Local)
        ↑
      CloudWatch (logs)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ Tech Stack
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Backend&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js + Express&lt;/li&gt;
&lt;li&gt;MongoDB + Mongoose&lt;/li&gt;
&lt;li&gt;CORS + dotenv&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker (containerization)&lt;/li&gt;
&lt;li&gt;Terraform (IaC)&lt;/li&gt;
&lt;li&gt;AWS ECR (image registry)&lt;/li&gt;
&lt;li&gt;AWS ECS Fargate (orchestration)&lt;/li&gt;
&lt;li&gt;AWS ALB (load balancing)&lt;/li&gt;
&lt;li&gt;AWS Secrets Manager (secure DB credentials)&lt;/li&gt;
&lt;li&gt;AWS IAM + Security Groups&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📁 Project Structure
&lt;/h2&gt;

&lt;p&gt;Your project is split into two main parts: &lt;strong&gt;app code&lt;/strong&gt; and &lt;strong&gt;infra code&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;manthanank-nodejs-terraform/
├── server.js                 # Express entry
├── Dockerfile                # Build container
├── config/db.js              # Mongo connection
├── controllers/todoController.js
├── models/Todo.js
├── routes/todoRoutes.js
├── terraform/                # Infrastructure as Code
│   ├── vpc.tf                # VPC + networking
│   ├── ecs.tf                # ECS cluster/service
│   ├── ecr.tf                # ECR repo
│   ├── iam.tf                # IAM roles/policies
│   ├── security.tf           # Security groups
│   ├── logs.tf               # CloudWatch logs
│   ├── secrets.tf            # Secrets Manager
│   ├── variables.tf          # Config vars
│   ├── outputs.tf            # Useful outputs
│   └── provider.tf           # AWS provider setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📝 Step 1 — Build the Node.js API
&lt;/h2&gt;

&lt;p&gt;Our CRUD endpoints live under &lt;code&gt;/api/todos&lt;/code&gt;.&lt;br&gt;
Example schema:&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;todoSchema&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="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;trim&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="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="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;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="na"&gt;createdAt&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;Date&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="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start locally:&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;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:5000/api/todos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📦 Step 2 — Dockerize the App
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Dockerfile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:18-alpine&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci &lt;span class="nt"&gt;--only&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PORT=5000&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 5000&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["node", "server.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; nodejs-todo-api &lt;span class="nb"&gt;.&lt;/span&gt;
docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 5000:5000 &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;MONGO_URI&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;your_mongo_uri nodejs-todo-api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ☁️ Step 3 — Terraform AWS Infrastructure
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Initialize
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;terraform
terraform init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Resources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ECR&lt;/strong&gt; — stores our container image (&lt;code&gt;ecr.tf&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ECS Fargate Service&lt;/strong&gt; — runs containers (&lt;code&gt;ecs.tf&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ALB + Target Group&lt;/strong&gt; — load balancing (&lt;code&gt;ecs.tf&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VPC + Subnets&lt;/strong&gt; — networking (&lt;code&gt;vpc.tf&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM Roles&lt;/strong&gt; — ECS execution permissions (&lt;code&gt;iam.tf&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secrets Manager&lt;/strong&gt; — injects &lt;code&gt;MONGO_URI&lt;/code&gt; securely (&lt;code&gt;secrets.tf&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch Logs&lt;/strong&gt; — for application logs (&lt;code&gt;logs.tf&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🐳 Step 4 — Push Image to ECR
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create the repo:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform apply &lt;span class="nt"&gt;-target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;aws_ecr_repository.app &lt;span class="nt"&gt;-auto-approve&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Build &amp;amp; push:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;AWS_ACCOUNT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws sts get-caller-identity &lt;span class="nt"&gt;--query&lt;/span&gt; Account &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ap-south-1
&lt;span class="nv"&gt;REPO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$AWS_ACCOUNT_ID&lt;/span&gt;.dkr.ecr.&lt;span class="nv"&gt;$REGION&lt;/span&gt;.amazonaws.com/node-crud-app
&lt;span class="nv"&gt;IMAGE_TAG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v1

docker build &lt;span class="nt"&gt;-t&lt;/span&gt; node-crud-app:&lt;span class="nv"&gt;$IMAGE_TAG&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
aws ecr get-login-password &lt;span class="nt"&gt;--region&lt;/span&gt; &lt;span class="nv"&gt;$REGION&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  docker login &lt;span class="nt"&gt;--username&lt;/span&gt; AWS &lt;span class="nt"&gt;--password-stdin&lt;/span&gt; &lt;span class="nv"&gt;$AWS_ACCOUNT_ID&lt;/span&gt;.dkr.ecr.&lt;span class="nv"&gt;$REGION&lt;/span&gt;.amazonaws.com
docker tag node-crud-app:&lt;span class="nv"&gt;$IMAGE_TAG&lt;/span&gt; &lt;span class="nv"&gt;$REPO&lt;/span&gt;:&lt;span class="nv"&gt;$IMAGE_TAG&lt;/span&gt;
docker push &lt;span class="nv"&gt;$REPO&lt;/span&gt;:&lt;span class="nv"&gt;$IMAGE_TAG&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🚀 Step 5 — Deploy with Terraform
&lt;/h2&gt;

&lt;p&gt;Apply the full infra:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Grab the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform output alb_dns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://&amp;lt;alb_dns&amp;gt;/api/todos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔄 Step 6 — Deploy Updates
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Build and push a new image with &lt;code&gt;IMAGE_TAG=v2&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Update &lt;code&gt;variables.tf&lt;/code&gt; → &lt;code&gt;image_tag = "v2"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform apply &lt;span class="nt"&gt;-var&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"image_tag=v2"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ECS performs a rolling update behind the ALB.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Monitoring &amp;amp; Logs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CloudWatch Logs&lt;/strong&gt;: All app logs stream automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ALB Health Checks&lt;/strong&gt;: Ensure tasks are healthy.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Troubleshooting&lt;/strong&gt;: Check ECS task logs in CloudWatch if service won’t start.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔒 Security Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;private subnets + NAT Gateway&lt;/strong&gt; in production.&lt;/li&gt;
&lt;li&gt;Restrict Secrets Manager IAM role to a single secret ARN.&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;immutable image tags&lt;/strong&gt; (&lt;code&gt;v1&lt;/code&gt;, &lt;code&gt;v2&lt;/code&gt;) instead of &lt;code&gt;latest&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;HTTPS&lt;/strong&gt; on ALB with ACM certificates.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;With just a few &lt;code&gt;.tf&lt;/code&gt; files, we’ve automated provisioning of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Containerized Node.js API&lt;/li&gt;
&lt;li&gt;Secure AWS networking &amp;amp; IAM&lt;/li&gt;
&lt;li&gt;Load-balanced ECS service&lt;/li&gt;
&lt;li&gt;Secrets and logs managed by AWS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach scales to any microservice — just add more services, modules, or CI/CD pipelines.&lt;/p&gt;




&lt;p&gt;✨ &lt;strong&gt;Pro tip&lt;/strong&gt;: Next step, integrate GitHub Actions or GitLab CI to automatically build/push Docker images and run &lt;code&gt;terraform apply&lt;/code&gt; for full CI/CD.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;🔗 GitHub Repository&lt;/strong&gt;: &lt;a href="https://github.com/manthanank/nodejs-terraform" rel="noopener noreferrer"&gt;manthanank/nodejs-terraform&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;🧑‍💻 Author&lt;/strong&gt;: &lt;a href="https://github.com/manthanank" rel="noopener noreferrer"&gt;Manthan Ankolekar&lt;/a&gt;&lt;/p&gt;




</description>
      <category>node</category>
      <category>aws</category>
      <category>terraform</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Terraform Setup Guide: Getting Started with Infrastructure as Code</title>
      <dc:creator>Manthan Ankolekar</dc:creator>
      <pubDate>Mon, 25 Aug 2025 10:16:48 +0000</pubDate>
      <link>https://dev.to/manthanank/terraform-setup-guide-getting-started-with-infrastructure-as-code-16k5</link>
      <guid>https://dev.to/manthanank/terraform-setup-guide-getting-started-with-infrastructure-as-code-16k5</guid>
      <description>&lt;p&gt;Terraform, developed by HashiCorp, is one of the most widely used tools for &lt;strong&gt;Infrastructure as Code (IaC)&lt;/strong&gt;. It allows you to define, provision, and manage cloud resources across providers like AWS, Azure, GCP, and many others using simple, declarative configuration files.&lt;/p&gt;

&lt;p&gt;If you’re just getting started, this guide will walk you through the &lt;strong&gt;setup process of Terraform&lt;/strong&gt;, from installation to writing your first configuration file.&lt;/p&gt;




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

&lt;p&gt;Before diving in, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A working terminal (Linux, macOS, or Windows with WSL/PowerShell).&lt;/li&gt;
&lt;li&gt;A cloud provider account (AWS, Azure, or GCP).&lt;/li&gt;
&lt;li&gt;Basic understanding of command line operations.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📥 Step 1: Install Terraform
&lt;/h2&gt;

&lt;h3&gt;
  
  
  On macOS (using Homebrew)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew tap hashicorp/tap
brew &lt;span class="nb"&gt;install &lt;/span&gt;hashicorp/tap/terraform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  On Linux (Debian/Ubuntu)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; gnupg software-properties-common
wget &lt;span class="nt"&gt;-O-&lt;/span&gt; https://apt.releases.hashicorp.com/gpg | gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /usr/share/keyrings/hashicorp-archive-keyring.gpg
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;lsb_release &lt;span class="nt"&gt;-cs&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt; main"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/hashicorp.list
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;terraform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  On Windows
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Download the Terraform binary from &lt;a href="https://developer.hashicorp.com/terraform/downloads" rel="noopener noreferrer"&gt;Terraform Downloads&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Extract the &lt;code&gt;.zip&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Add the Terraform binary path to your &lt;strong&gt;System Environment Variables&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;✅ Verify installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  📂 Step 2: Configure Cloud Provider Access
&lt;/h2&gt;

&lt;p&gt;Terraform uses provider plugins (like AWS, Azure, GCP). You’ll need credentials to let Terraform interact with your cloud.&lt;/p&gt;

&lt;h3&gt;
  
  
  AWS Example
&lt;/h3&gt;

&lt;p&gt;Install AWS CLI and configure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws configure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS Access Key ID&lt;/li&gt;
&lt;li&gt;AWS Secret Access Key&lt;/li&gt;
&lt;li&gt;Default region&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Terraform will automatically use these credentials.&lt;/p&gt;




&lt;h2&gt;
  
  
  📝 Step 3: Create Your First Terraform Project
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create a new project folder:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;terraform-setup &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;terraform-setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create a configuration file &lt;code&gt;main.tf&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-terraform-setup-bucket"&lt;/span&gt;
  &lt;span class="nx"&gt;acl&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"private"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defines AWS as the provider.&lt;/li&gt;
&lt;li&gt;Creates a private S3 bucket named &lt;code&gt;my-terraform-setup-bucket&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ▶️ Step 4: Initialize Terraform
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This downloads necessary plugins (e.g., AWS provider).&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 Step 5: Validate and Plan
&lt;/h2&gt;

&lt;p&gt;Check if configuration is valid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Preview changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🚀 Step 6: Apply Configuration
&lt;/h2&gt;

&lt;p&gt;Deploy resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type &lt;code&gt;yes&lt;/code&gt; when prompted. Terraform will create the S3 bucket.&lt;/p&gt;




&lt;h2&gt;
  
  
  🗑 Step 7: Destroy Resources
&lt;/h2&gt;

&lt;p&gt;To clean up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm with &lt;code&gt;yes&lt;/code&gt;.&lt;/p&gt;




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

&lt;p&gt;You’ve successfully installed and set up Terraform, configured your first provider, and deployed an AWS S3 bucket. From here, you can scale to more complex infrastructures—VPCs, databases, load balancers, Kubernetes clusters, and beyond.&lt;/p&gt;

&lt;p&gt;By mastering Terraform, you’ll gain full control over your infrastructure in a reproducible, version-controlled, and automated way.&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>devops</category>
    </item>
    <item>
      <title>Essential Terraform CLI Commands You Should Know</title>
      <dc:creator>Manthan Ankolekar</dc:creator>
      <pubDate>Wed, 20 Aug 2025 05:03:24 +0000</pubDate>
      <link>https://dev.to/manthanank/essential-terraform-cli-commands-you-should-know-504f</link>
      <guid>https://dev.to/manthanank/essential-terraform-cli-commands-you-should-know-504f</guid>
      <description>&lt;p&gt;Terraform is one of the most popular Infrastructure as Code (IaC) tools, allowing developers and DevOps engineers to define and provision cloud resources in a declarative way. The &lt;strong&gt;Terraform CLI (Command Line Interface)&lt;/strong&gt; is the primary way to interact with Terraform — from initializing projects to applying infrastructure changes.&lt;/p&gt;

&lt;p&gt;In this blog, we’ll go through the most commonly used Terraform CLI commands with examples.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. &lt;code&gt;terraform init&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The very first command you run in a new Terraform project.&lt;br&gt;
It initializes the working directory, downloads the required provider plugins, and sets up the backend.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Run this whenever you start a new project or modify providers/backends.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. &lt;code&gt;terraform validate&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Validates the configuration files in your project to ensure there are no syntax or logical errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Helps catch issues early before running &lt;code&gt;plan&lt;/code&gt; or &lt;code&gt;apply&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. &lt;code&gt;terraform plan&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Generates an &lt;strong&gt;execution plan&lt;/strong&gt; showing what actions Terraform will take (create, update, destroy resources).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also save the plan to a file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform plan &lt;span class="nt"&gt;-out&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;tfplan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Use this before applying changes to confirm what Terraform will do.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. &lt;code&gt;terraform apply&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Applies the planned changes to your infrastructure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or apply a saved plan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform apply tfplan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 This is the command that actually &lt;strong&gt;provisions resources&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. &lt;code&gt;terraform destroy&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Destroys all resources defined in the Terraform configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Be careful! This will tear down your infrastructure.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. &lt;code&gt;terraform show&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Displays information about your Terraform state or saved plan.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform show
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Useful for inspecting what’s deployed.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. &lt;code&gt;terraform output&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Shows output values defined in your &lt;code&gt;outputs.tf&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Great for retrieving information like IP addresses, instance IDs, etc.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. &lt;code&gt;terraform state&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Manages the Terraform state file. Common subcommands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;List resources in state:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  terraform state list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Show details about a specific resource:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  terraform state show aws_instance.example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Use this for debugging or manual state inspection.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. &lt;code&gt;terraform fmt&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Formats Terraform configuration files (&lt;code&gt;.tf&lt;/code&gt;) to a canonical style.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform &lt;span class="nb"&gt;fmt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Helps maintain clean, consistent code formatting.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. &lt;code&gt;terraform version&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Displays the currently installed Terraform version.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Always good to verify when collaborating across teams.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Reference Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;terraform init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Initialize project &amp;amp; download providers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;terraform validate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Validate config files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;terraform plan&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Preview execution plan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;terraform apply&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Apply infrastructure changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;terraform destroy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Destroy resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;terraform show&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show state or plan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;terraform output&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Display output values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;terraform state&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Manage state file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;terraform fmt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Format configuration files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;terraform version&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Show Terraform version&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




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

&lt;p&gt;Terraform CLI commands are the backbone of working with Infrastructure as Code. By mastering these commands, you’ll be able to confidently manage cloud resources across providers like AWS, Azure, and GCP.&lt;/p&gt;

&lt;p&gt;Whether you’re just starting with Terraform or already deploying production workloads, these commands should be part of your daily toolkit.&lt;/p&gt;




</description>
      <category>terraform</category>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>🚀 Automate Media Uploads to Cloudinary with Node.js: A Complete Guide</title>
      <dc:creator>Manthan Ankolekar</dc:creator>
      <pubDate>Thu, 07 Aug 2025 05:12:50 +0000</pubDate>
      <link>https://dev.to/manthanank/automate-media-uploads-to-cloudinary-with-nodejs-a-complete-guide-1eah</link>
      <guid>https://dev.to/manthanank/automate-media-uploads-to-cloudinary-with-nodejs-a-complete-guide-1eah</guid>
      <description>&lt;p&gt;Managing media uploads manually can be a pain — especially when you're dealing with hundreds of images and videos. Whether you're a content creator, developer, or business owner, storing media in the cloud should be fast, organized, and reliable.&lt;/p&gt;

&lt;p&gt;That's where &lt;strong&gt;Cloudinary Uploader&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;Built with Node.js, this open-source tool automates the process of uploading images and videos from a local folder to Cloudinary. It supports batch processing, multi-format handling, retry logic, and more.&lt;/p&gt;

&lt;p&gt;Let’s dive into how it works and how you can get started in minutes.&lt;/p&gt;




&lt;h2&gt;
  
  
  🌟 Why Use This Uploader?
&lt;/h2&gt;

&lt;p&gt;Here’s what makes &lt;strong&gt;Cloudinary Uploader&lt;/strong&gt; stand out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔄 &lt;strong&gt;Bulk Upload&lt;/strong&gt;: Upload dozens or even hundreds of media files in one go.&lt;/li&gt;
&lt;li&gt;☁️ &lt;strong&gt;Cloud Storage&lt;/strong&gt;: Securely store media on Cloudinary.&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Smart Detection&lt;/strong&gt;: Automatically detects and separates images from videos.&lt;/li&gt;
&lt;li&gt;📦 &lt;strong&gt;Batch Processing&lt;/strong&gt;: Upload files in customizable batch sizes.&lt;/li&gt;
&lt;li&gt;♻️ &lt;strong&gt;Retry Mechanism&lt;/strong&gt;: Automatically retries failed uploads.&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;Detailed Summary&lt;/strong&gt;: Get a clear report of success and failure rates.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ Features at a Glance
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Supported Formats&lt;/td&gt;
&lt;td&gt;Images: PNG, JPG, GIF, SVG, WebP, etc. &lt;br&gt; Videos: MP4, AVI, MOV, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Organized Uploads&lt;/td&gt;
&lt;td&gt;Uploads are organized into &lt;code&gt;images/&lt;/code&gt; and &lt;code&gt;videos/&lt;/code&gt; folders in Cloudinary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Retry Logic&lt;/td&gt;
&lt;td&gt;Configurable retry attempts for failed uploads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Batch Configuration&lt;/td&gt;
&lt;td&gt;Upload files in batches (default: 10 per batch)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CLI Monitoring&lt;/td&gt;
&lt;td&gt;Real-time progress updates in the terminal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📁 Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cloudinary-uploader/
├── images/           # Place your media files here
├── index.js          # Main script
├── .env              # Your Cloudinary credentials (not committed)
├── .env.example      # Example for setting up your env file
├── package.json      # Project metadata and dependencies
└── README.md         # Project documentation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🚀 Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Clone the Repository
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/manthanank/cloudinary-uploader.git
&lt;span class="nb"&gt;cd &lt;/span&gt;cloudinary-uploader
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Install Dependencies
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Configure Environment Variables
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;.env&lt;/code&gt; file based on the provided &lt;code&gt;.env.example&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Find these credentials in your Cloudinary dashboard.&lt;/p&gt;




&lt;h2&gt;
  
  
  🖼️ Uploading Media
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Place all your images and videos inside the &lt;code&gt;images/&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;Run the uploader:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll see real-time logs like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📁 Found 150 media files to upload
🖼️  Images: 120
🎥 Videos: 30
⚙️  Processing in batches of 10 files
🔄 Retry attempts: 3
...
🎥 Uploaded video1.mp4 (video): https://res.cloudinary.com/demo/video/upload/videos/video1.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ Customization Options
&lt;/h2&gt;

&lt;h3&gt;
  
  
  📐 Batch Size &amp;amp; Retry Attempts
&lt;/h3&gt;

&lt;p&gt;You can adjust these in &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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BATCH_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;       &lt;span class="c1"&gt;// Upload 10 files per batch&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RETRY_ATTEMPTS&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="c1"&gt;// Retry failed uploads 3 times&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RETRY_DELAY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="c1"&gt;// Delay between retries (in ms)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ➕ Add More File Types
&lt;/h3&gt;

&lt;p&gt;To support additional formats, modify the extension arrays:&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;IMAGE_EXTENSIONS&lt;/span&gt; &lt;span class="o"&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;VIDEO_EXTENSIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧪 Error Handling &amp;amp; Troubleshooting
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Solution&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;❌ Folder not found&lt;/td&gt;
&lt;td&gt;Ensure &lt;code&gt;images/&lt;/code&gt; exists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;❌ Invalid credentials&lt;/td&gt;
&lt;td&gt;Check your &lt;code&gt;.env&lt;/code&gt; file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;❌ Upload failed&lt;/td&gt;
&lt;td&gt;Check file format, size, internet connection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;❌ Resource type error&lt;/td&gt;
&lt;td&gt;Verify correct file extension&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  📊 Upload Summary
&lt;/h2&gt;

&lt;p&gt;At the end of each run, you’ll see a detailed summary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;📊 Upload Summary:
🖼️  Images - ✅ Successful: 118, ❌ Failed: 2
🎥 Videos - ✅ Successful: 30, ❌ Failed: 0
📈 Overall Success Rate: 98.7%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔐 Security Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Never commit your &lt;code&gt;.env&lt;/code&gt; file to version control&lt;/li&gt;
&lt;li&gt;Store your credentials securely (e.g., use CI/CD secrets in production)&lt;/li&gt;
&lt;li&gt;Cloudinary uses secure URLs by default for all media&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📦 Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt;: Core runtime&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloudinary SDK&lt;/strong&gt;: Media upload API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dotenv&lt;/strong&gt;: Load environment variables&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fs &amp;amp; path&lt;/strong&gt;: File system utilities&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧑‍💻 Contributing
&lt;/h2&gt;

&lt;p&gt;Want to improve this project?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fork the repo&lt;/li&gt;
&lt;li&gt;Create a new feature branch&lt;/li&gt;
&lt;li&gt;Commit and push your changes&lt;/li&gt;
&lt;li&gt;Submit a pull request 🚀&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  📘 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;If you're tired of dragging and dropping files into a web dashboard, &lt;strong&gt;Cloudinary Uploader&lt;/strong&gt; offers a powerful alternative. With just one command, you can upload hundreds of images and videos into organized Cloudinary folders — complete with progress tracking and error handling.&lt;/p&gt;

&lt;p&gt;Give it a try and streamline your media management today.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;🔗 GitHub Repository&lt;/strong&gt;: &lt;a href="https://github.com/manthanank/cloudinary-uploader" rel="noopener noreferrer"&gt;manthanank/cloudinary-uploader&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;🧑‍💻 Author&lt;/strong&gt;: &lt;a href="https://github.com/manthanank" rel="noopener noreferrer"&gt;Manthan Ankolekar&lt;/a&gt;&lt;/p&gt;




</description>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>🚀 Building an AI-Powered Resume Optimizer with Angular, Node.js &amp; Gemini</title>
      <dc:creator>Manthan Ankolekar</dc:creator>
      <pubDate>Wed, 23 Jul 2025 04:47:09 +0000</pubDate>
      <link>https://dev.to/manthanank/building-an-ai-powered-resume-optimizer-with-angular-nodejs-gemini-44d8</link>
      <guid>https://dev.to/manthanank/building-an-ai-powered-resume-optimizer-with-angular-nodejs-gemini-44d8</guid>
      <description>&lt;p&gt;&lt;strong&gt;Struggling to tailor your resume for specific job postings?&lt;/strong&gt; I built an AI-powered Resume Optimizer that helps you analyze your resume against any job description using Google Gemini. Here's how I built it using the &lt;strong&gt;MEAN stack&lt;/strong&gt; (MongoDB-free) with Angular standalone components, Tailwind CSS, and Google’s Generative AI API.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 Why I Built This
&lt;/h2&gt;

&lt;p&gt;Every job role has unique expectations, but most resumes stay generic. I wanted to automate the process of &lt;strong&gt;matching resumes with job descriptions&lt;/strong&gt;, highlighting what's missing, and suggesting improvements—all with the power of AI.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 Tech Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Stack&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Angular 20, Standalone Components, Tailwind CSS, Signals, Reactive Forms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Node.js, Express, Multer&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI Engine&lt;/td&gt;
&lt;td&gt;Google Gemini via &lt;code&gt;@google/genai&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parsing&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;pdf-parse&lt;/code&gt; and &lt;code&gt;mammoth&lt;/code&gt; for file extraction&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🧠 Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ Upload Resume (PDF or DOCX)&lt;/li&gt;
&lt;li&gt;✅ Upload or Paste Job Description&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Get AI analysis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Match Score&lt;/li&gt;
&lt;li&gt;Missing Keywords&lt;/li&gt;
&lt;li&gt;Tailored Suggestions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;&lt;p&gt;🌗 Dark Mode Support&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;📱 Fully Responsive UI&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 System Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Angular UI] --&amp;gt; [Express API] --&amp;gt; [Gemini API]
                    |
             [PDF/DOCX Parser]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🖥️ Frontend Highlights
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Standalone Angular Components&lt;/li&gt;
&lt;li&gt;Signals for local state (&lt;code&gt;resumeFile&lt;/code&gt;, &lt;code&gt;jdFile&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;li&gt;Native control flow (&lt;code&gt;@if&lt;/code&gt;, &lt;code&gt;@else&lt;/code&gt;) over structural directives&lt;/li&gt;
&lt;li&gt;Reactive Forms for input validation&lt;/li&gt;
&lt;li&gt;Markdown rendering using &lt;code&gt;ngx-markdown&lt;/code&gt; for AI response formatting
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fb&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nonNullable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;group&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;jdText&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resumeFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;File&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;signal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔧 Backend Highlights
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;File parsing using &lt;code&gt;pdf-parse&lt;/code&gt; (PDF) and &lt;code&gt;mammoth&lt;/code&gt; (DOCX)&lt;/li&gt;
&lt;li&gt;Gemini prompt format:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Compare the following resume and job description. Provide:
- Match score (0-100)
- Missing keywords
- Suggested improvements
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;AI integration via &lt;code&gt;@google/genai&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ai&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;GoogleGenAI&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;apiKey&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;GEMINI_API_KEY&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;response&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;ai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateContent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&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;gemini-2.5-flash&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🚀 How to Run It Locally
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🔗 Clone the Project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/manthanank/resume-optimizer.git
&lt;span class="nb"&gt;cd &lt;/span&gt;resume-optimizer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ⚙️ Backend Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;backend
npm &lt;span class="nb"&gt;install
cp&lt;/span&gt; .env.example .env
&lt;span class="c"&gt;# Add your GEMINI_API_KEY&lt;/span&gt;
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🌐 Frontend Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;frontend
npm &lt;span class="nb"&gt;install
&lt;/span&gt;ng serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🌐 Hosted Live (Demo)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Frontend: &lt;a href="https://resume-optimizer-app.vercel.app" rel="noopener noreferrer"&gt;https://resume-optimizer-app.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Backend API: &lt;a href="https://resume-optimizer-api.vercel.app" rel="noopener noreferrer"&gt;https://resume-optimizer-api.vercel.app&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📦 Future Improvements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🔐 Auth for saving resume history&lt;/li&gt;
&lt;li&gt;📝 Editable resume templates&lt;/li&gt;
&lt;li&gt;📄 PDF download of feedback&lt;/li&gt;
&lt;li&gt;🌍 Multi-language support&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📃 License
&lt;/h2&gt;

&lt;p&gt;MIT — Free to use and modify. Contributions welcome!&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This project taught me how to combine real-time file processing with AI content generation in a full-stack TypeScript environment. Whether you're building something for HR, job seekers, or just love AI—this app is a perfect side project to learn from.&lt;/p&gt;




&lt;p&gt;👉 Want to try it?&lt;br&gt;
&lt;strong&gt;&lt;a href="https://github.com/manthanank/resume-optimizer" rel="noopener noreferrer"&gt;🔗 GitHub Repo&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;&lt;a href="https://resume-optimizer-app.vercel.app" rel="noopener noreferrer"&gt;🚀 Live Demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>angular</category>
    </item>
    <item>
      <title>Exploring Binary Assignment Operators with Angular v20.1.0 🚀</title>
      <dc:creator>Manthan Ankolekar</dc:creator>
      <pubDate>Mon, 21 Jul 2025 06:32:47 +0000</pubDate>
      <link>https://dev.to/manthanank/exploring-binary-assignment-operators-with-angular-v2010-g16</link>
      <guid>https://dev.to/manthanank/exploring-binary-assignment-operators-with-angular-v2010-g16</guid>
      <description>&lt;p&gt;If you're learning JavaScript or Angular and want to better understand how binary assignment operators work, this simple interactive Angular project is just for you.&lt;/p&gt;

&lt;p&gt;We often use operators like &lt;code&gt;+=&lt;/code&gt;, &lt;code&gt;*=&lt;/code&gt;, &lt;code&gt;||=&lt;/code&gt;, and &lt;code&gt;??=&lt;/code&gt; in our code—but rarely see them in action visually. That’s where this app comes in. Built with Angular 20, it's a lightweight demo that helps you learn through interaction, not just theory.&lt;/p&gt;




&lt;h2&gt;
  
  
  💡 What Does the App Do?
&lt;/h2&gt;

&lt;p&gt;This Angular app demonstrates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mathematical operations&lt;/strong&gt; like increment, decrement, multiply, square.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logical operations&lt;/strong&gt; like setting a message only if empty, or resetting a flag only if true.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nullish coalescing behavior&lt;/strong&gt; using &lt;code&gt;??=&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It uses Angular’s built-in event bindings to update values instantly on button click and reflects those changes on the screen.&lt;/p&gt;




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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;manthanank-angular-examples/
├── src/
│   └── app/
│       ├── app.ts
│       ├── app.html
│       ├── app.css
│       └── app.config.ts
├── angular.json
├── package.json
└── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🖥️ The User Interface
&lt;/h2&gt;

&lt;p&gt;The UI is clean and split into three sections:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. 🔢 Count Operations
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"count += 1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Increment (+1)&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"count -= 1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Decrement (-1)&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"count *= multiplier"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Multiply&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"count **= 2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Square&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These buttons perform typical arithmetic updates on a &lt;code&gt;count&lt;/code&gt; variable.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. 💬 Message Controls
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"message ||= 'Hello, Angular!'"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Set Message if Empty&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"message &amp;amp;&amp;amp;= ''"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Clear Message if Exists&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can conditionally set or clear a message based on its current value.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. ✅ Boolean Logic
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"condition ??= true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Set if Undefined / Null&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"condition &amp;amp;&amp;amp;= false"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Reset if True&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A neat way to visualize boolean flag logic!&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ How to Run the App
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Clone the Repo
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/manthanank/angular-examples.git
&lt;span class="nb"&gt;cd &lt;/span&gt;angular-examples
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Install Dependencies
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Run the Development Server
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visit &lt;code&gt;http://localhost:4200&lt;/code&gt; in your browser to see it live.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ Running Tests
&lt;/h2&gt;

&lt;p&gt;Execute unit tests with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This runs the included specs using Karma and Jasmine.&lt;/p&gt;




&lt;h2&gt;
  
  
  📚 What You’ll Learn
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Core Angular concepts like component structure, event binding, and template rendering&lt;/li&gt;
&lt;li&gt;Practical use of JavaScript operators like &lt;code&gt;||=&lt;/code&gt;, &lt;code&gt;&amp;amp;&amp;amp;=&lt;/code&gt;, &lt;code&gt;??=&lt;/code&gt;, &lt;code&gt;+=&lt;/code&gt;, &lt;code&gt;**=&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A modular and clean Angular 20 project setup&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🏁 Final Words
&lt;/h2&gt;

&lt;p&gt;Learning doesn't always have to be complex. This Angular app is a simple and visual way to deepen your understanding of binary assignment operators—and sharpen your Angular skills at the same time.&lt;/p&gt;

&lt;p&gt;🔗 Check out the code here: &lt;a href="https://github.com/manthanank/angular-examples/tree/binary-operators" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>angular</category>
      <category>beginners</category>
    </item>
    <item>
      <title>🚀 Build a Prompt Generator App with Angular, Tailwind CSS &amp; Google Gemini API</title>
      <dc:creator>Manthan Ankolekar</dc:creator>
      <pubDate>Thu, 17 Jul 2025 05:02:51 +0000</pubDate>
      <link>https://dev.to/manthanank/build-a-prompt-generator-app-with-angular-tailwind-css-google-gemini-api-g2d</link>
      <guid>https://dev.to/manthanank/build-a-prompt-generator-app-with-angular-tailwind-css-google-gemini-api-g2d</guid>
      <description>&lt;p&gt;If you're looking to explore Generative AI in your Angular apps, this blog is for you! Learn how I built a modern, full-featured &lt;strong&gt;Prompt Generator&lt;/strong&gt; using Angular, Tailwind CSS, and the &lt;strong&gt;Gemini API&lt;/strong&gt;—with a secure Node.js/Express backend to keep things safe.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌟 What Is the Prompt Generator?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Prompt Generator&lt;/strong&gt; is a web app that allows you to:&lt;/p&gt;

&lt;p&gt;✅ Generate creative, formal, funny, or concise AI prompts&lt;br&gt;
✅ Copy or save prompts to favorites&lt;br&gt;
✅ View history of generated prompts&lt;br&gt;
✅ Toggle between light and dark mode&lt;br&gt;
✅ Enjoy a responsive and modern UI with Tailwind CSS&lt;br&gt;
✅ Use a secure backend to protect your API key&lt;/p&gt;

&lt;p&gt;Live Demo: &lt;a href="https://prompt-generator-application.vercel.app/" rel="noopener noreferrer"&gt;prompt-generator-application.vercel.app&lt;/a&gt;&lt;br&gt;
GitHub Repo: &lt;a href="https://github.com/manthanank/prompt-generator" rel="noopener noreferrer"&gt;https://github.com/manthanank/prompt-generator&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  🏗️ Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: Angular 20+, Tailwind CSS 4, ngx-markdown&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Node.js + Express&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Engine&lt;/strong&gt;: Google Gemini Pro (via &lt;code&gt;@google/genai&lt;/code&gt; SDK)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🔒 Why Use a Backend?
&lt;/h2&gt;

&lt;p&gt;Google's Gemini API requires your API key. Exposing it in frontend code is risky. That's why this app routes all AI requests through a secure &lt;strong&gt;Express server&lt;/strong&gt;, hosted on &lt;a href="https://vercel.com" rel="noopener noreferrer"&gt;Vercel&lt;/a&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  📁 Project Structure
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;prompt-generator/
├── backend/          → Express API for Gemini
├── src/              → Angular frontend
│   ├── app/          → Standalone Angular components
│   ├── environments/ → Environment config
│   └── styles.css    → Tailwind + Dark mode styles
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔧 Setup &amp;amp; Installation
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Clone the Repository
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/manthanank/prompt-generator.git
&lt;span class="nb"&gt;cd &lt;/span&gt;prompt-generator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  2. Install Frontend &amp;amp; Backend Dependencies
&lt;/h3&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
cd &lt;/span&gt;backend
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  3. Configure the Environment
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;.env&lt;/code&gt; file inside &lt;code&gt;backend/&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GEMINI_API_KEY=your_gemini_api_key_here
PORT=3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Start Development Servers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# In backend/&lt;/span&gt;
npm start

&lt;span class="c"&gt;# In frontend (root)&lt;/span&gt;
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧠 How It Works
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🧾 Prompt Generation Flow:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;User Input&lt;/strong&gt;: Choose style + enter description&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Call&lt;/strong&gt;: Angular sends prompt to Express backend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gemini API&lt;/strong&gt;: Generates high-quality content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Display&lt;/strong&gt;: Angular shows the markdown-formatted result&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extras&lt;/strong&gt;: History, Favorites, Copy to Clipboard, Dark Mode&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  ✨ Highlight Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🗂️ Prompt Styles
&lt;/h3&gt;

&lt;p&gt;Choose from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creative&lt;/li&gt;
&lt;li&gt;Formal&lt;/li&gt;
&lt;li&gt;Funny&lt;/li&gt;
&lt;li&gt;Concise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each style is prepended to the user’s input to guide the AI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;styledInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`Generate a &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;style&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="s2"&gt; prompt for: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;userInput&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  📜 Markdown Rendering with ngx-markdown
&lt;/h3&gt;

&lt;p&gt;Gemini returns responses with headings, lists, and bold text. To display this nicely, we use &lt;a href="https://www.npmjs.com/package/ngx-markdown" rel="noopener noreferrer"&gt;&lt;code&gt;ngx-markdown&lt;/code&gt;&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;markdown&lt;/span&gt; &lt;span class="na"&gt;[data]=&lt;/span&gt;&lt;span class="s"&gt;"generatedPrompt"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/markdown&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  💡 Favorites &amp;amp; History with localStorage
&lt;/h3&gt;

&lt;p&gt;Save your best prompts or revisit recent ones!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;favorites&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;favoritePrompts&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🌓 Dark Mode with Tailwind + Signals
&lt;/h3&gt;

&lt;p&gt;Using Angular Signals and Tailwind dark classes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;toggleDarkMode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;darkMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;documentElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;darkMode&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  🔐 Backend: Express + Gemini API
&lt;/h3&gt;

&lt;p&gt;Secure route that proxies requests to Gemini:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;app&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;/generate-content&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;userPrompt&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="nx"&gt;response&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;ai&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateContent&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&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;gemini-2.5-flash&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userPrompt&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;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hosted via Vercel with a &lt;code&gt;vercel.json&lt;/code&gt; config.&lt;/p&gt;




&lt;h2&gt;
  
  
  🌍 Deployment Options
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ Frontend: GitHub Pages / Vercel / Netlify&lt;/li&gt;
&lt;li&gt;✅ Backend: Vercel Serverless Function or Railway&lt;/li&gt;
&lt;li&gt;✅ Environment: Environment-safe with &lt;code&gt;.env&lt;/code&gt; &amp;amp; build-time env usage&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📸 Screenshots
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;(Add screenshots of UI, light/dark modes, mobile view, etc.)&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧩 Future Enhancements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✍️ Prompt Templates&lt;/li&gt;
&lt;li&gt;🔐 Login with Google (Firebase Auth)&lt;/li&gt;
&lt;li&gt;📊 Prompt analytics&lt;/li&gt;
&lt;li&gt;🗃️ Export to PDF or Markdown&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📜 License
&lt;/h2&gt;

&lt;p&gt;MIT © &lt;a href="https://github.com/manthanank" rel="noopener noreferrer"&gt;Manthan Ankolekar&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🙌 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Building this project was a great exercise in combining the power of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Angular Standalone Components + Signals&lt;/li&gt;
&lt;li&gt;Tailwind’s dark mode utility&lt;/li&gt;
&lt;li&gt;AI text generation via Google Gemini&lt;/li&gt;
&lt;li&gt;And clean local storage features&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;🔗 Check it out: &lt;a href="https://prompt-generator-application.vercel.app/" rel="noopener noreferrer"&gt;prompt-generator-application.vercel.app&lt;/a&gt;&lt;br&gt;
📦 View the Code: &lt;a href="https://github.com/manthanank/prompt-generator" rel="noopener noreferrer"&gt;github.com/manthanank/prompt-generator&lt;/a&gt;&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>programming</category>
      <category>angular</category>
      <category>beginners</category>
    </item>
    <item>
      <title>🚗 Build a Ride Cost Calculator App with Angular 20 and Tailwind CSS 4</title>
      <dc:creator>Manthan Ankolekar</dc:creator>
      <pubDate>Mon, 30 Jun 2025 04:35:50 +0000</pubDate>
      <link>https://dev.to/manthanank/build-a-ride-cost-calculator-app-with-angular-20-and-tailwind-css-4-ao3</link>
      <guid>https://dev.to/manthanank/build-a-ride-cost-calculator-app-with-angular-20-and-tailwind-css-4-ao3</guid>
      <description>&lt;p&gt;Managing fuel expenses is essential whether you're a frequent commuter or a casual rider. In this blog, I’ll walk you through how I built a modern &lt;strong&gt;Ride Cost Calculator App&lt;/strong&gt; using &lt;strong&gt;Angular 20&lt;/strong&gt;, &lt;strong&gt;Tailwind CSS 4&lt;/strong&gt;, and the latest &lt;strong&gt;signals API&lt;/strong&gt; from Angular.&lt;/p&gt;

&lt;p&gt;This sleek, mobile-responsive app helps you estimate ride costs, track history, and even export or print receipts.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🔗 &lt;strong&gt;Source Code:&lt;/strong&gt; &lt;a href="https://github.com/manthanank/ride-cost-calculator-app" rel="noopener noreferrer"&gt;GitHub – manthanank/ride-cost-calculator-app&lt;/a&gt;&lt;br&gt;
🚀 &lt;strong&gt;Live Demo:&lt;/strong&gt; &lt;a href="https://ride-cost-calculator-app.vercel.app/" rel="noopener noreferrer"&gt;ride-cost-calculator-app.vercel.app&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  ✨ Features at a Glance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🚀 Real-time fuel cost calculation&lt;/li&gt;
&lt;li&gt;📊 Persistent ride history (local storage)&lt;/li&gt;
&lt;li&gt;📁 Export ride history as CSV&lt;/li&gt;
&lt;li&gt;🖨️ Print ride receipts&lt;/li&gt;
&lt;li&gt;🌍 Choose currency (₹/\$/€) and unit (km/mi)&lt;/li&gt;
&lt;li&gt;🌓 Toggle light/dark mode&lt;/li&gt;
&lt;li&gt;🔁 Responsive design for all screen sizes&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔧 Tech Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Angular 20&lt;/strong&gt; – Standalone components &amp;amp; Signals&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind CSS 4&lt;/strong&gt; – Utility-first styling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript&lt;/strong&gt; – Strictly typed reactive app&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostCSS&lt;/strong&gt; – Tailwind configuration&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧮 How the Calculator Works
&lt;/h2&gt;

&lt;p&gt;The calculator uses this formula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Total Cost = (Distance / Mileage) × Petrol Price
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Distance in &lt;strong&gt;km&lt;/strong&gt; or &lt;strong&gt;miles&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Fuel prices in &lt;strong&gt;₹, \$, €&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Mileage in &lt;strong&gt;km/l&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The app auto-converts miles to kilometers before calculation and provides a cost breakdown with fuel efficiency tips.&lt;/p&gt;




&lt;h2&gt;
  
  
  📊 Ride History with Export &amp;amp; Print
&lt;/h2&gt;

&lt;p&gt;Every ride you calculate is saved locally and appears in a history list. From there, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧾 &lt;strong&gt;Print&lt;/strong&gt; a ride receipt&lt;/li&gt;
&lt;li&gt;📥 &lt;strong&gt;Export&lt;/strong&gt; all records as a CSV&lt;/li&gt;
&lt;li&gt;🧹 &lt;strong&gt;Clear&lt;/strong&gt; history with one click&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CSV export is handled by dynamically generating a blob and creating a download link. Printing is done in a new browser window with minimal styling.&lt;/p&gt;




&lt;h2&gt;
  
  
  🌓 Dark Mode &amp;amp; Signals
&lt;/h2&gt;

&lt;p&gt;The app uses &lt;strong&gt;Angular Signals&lt;/strong&gt; to track and react to state changes like theme preference, ride input, and form reset. Theme mode is persisted in &lt;code&gt;localStorage&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newTheme&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;isDarkMode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;theme-preference&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;newTheme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🗂️ Project Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ride-cost-calculator-app/
├── src/
│   ├── app/
│   │   ├── components/
│   │   ├── models/
│   │   └── services/
│   ├── environments/
│   └── styles.css  ← Tailwind imported here
├── public/
├── angular.json
├── package.json
└── .postcssrc.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ▶️ Get Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Clone &amp;amp; Install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/manthanank/ride-cost-calculator-app.git
&lt;span class="nb"&gt;cd &lt;/span&gt;ride-cost-calculator-app
npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run Locally
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng serve
&lt;span class="c"&gt;# Open http://localhost:4200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Build for Production
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng build &lt;span class="nt"&gt;--configuration&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  💬 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;This Ride Cost Calculator App is more than just a fuel estimator. It's a demonstration of &lt;strong&gt;modern Angular capabilities&lt;/strong&gt; using &lt;strong&gt;signals&lt;/strong&gt;, &lt;strong&gt;defer blocks&lt;/strong&gt;, and &lt;strong&gt;standalone architecture&lt;/strong&gt;, all styled elegantly with &lt;strong&gt;Tailwind CSS&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Whether you're tracking daily commutes or planning a road trip, this tool brings clarity to your fuel expenses — with a delightful user experience.&lt;/p&gt;




&lt;p&gt;🔗 &lt;strong&gt;Check it out: &lt;a href="https://ride-cost-calculator-app.vercel.app/" rel="noopener noreferrer"&gt;ride-cost-calculator-app.vercel.app&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
📦 &lt;strong&gt;View the Code: &lt;a href="https://github.com/manthanank/ride-cost-calculator-app" rel="noopener noreferrer"&gt;github.com/manthanank/ride-cost-calculator-app&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>angular</category>
    </item>
    <item>
      <title>Peeking Under the Hood: How to List Your npm Packages</title>
      <dc:creator>Manthan Ankolekar</dc:creator>
      <pubDate>Fri, 30 May 2025 07:07:22 +0000</pubDate>
      <link>https://dev.to/manthanank/peeking-under-the-hood-how-to-list-your-npm-packages-205b</link>
      <guid>https://dev.to/manthanank/peeking-under-the-hood-how-to-list-your-npm-packages-205b</guid>
      <description>&lt;p&gt;As developers, we spend a lot of time installing packages. Whether it's a new framework, a handy utility, or a build tool, &lt;code&gt;npm install&lt;/code&gt; is a command we type almost subconsciously. But how often do we stop to consider what's actually installed on our system or within our projects?&lt;/p&gt;

&lt;p&gt;Knowing how to list your npm packages is more than just curiosity; it's a fundamental skill for debugging, understanding project dependencies, and maintaining a healthy development environment. Let's dive into the essential commands you need to master.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why List Your npm Packages?
&lt;/h3&gt;

&lt;p&gt;Before we get to the "how," let's quickly touch on the "why":&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Debugging:&lt;/strong&gt; Is your build failing? A conflicting package version might be the culprit. Listing packages helps you identify what's actually installed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auditing:&lt;/strong&gt; Want to check if a specific package (or an outdated version) is lurking in your project?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understanding Dependencies:&lt;/strong&gt; For new team members, listing packages provides a quick overview of a project's ecosystem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cleanup:&lt;/strong&gt; Identifying globally installed packages you no longer use can help keep your system tidy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Essential &lt;code&gt;npm list&lt;/code&gt; Command
&lt;/h3&gt;

&lt;p&gt;The core command for this task is &lt;code&gt;npm list&lt;/code&gt;. However, used on its own, it can sometimes feel like drinking from a firehose, especially in large projects. That's why we use some helpful flags to refine the output.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Listing Global Packages: Your System-Wide Tools
&lt;/h4&gt;

&lt;p&gt;Global packages are those installed with the &lt;code&gt;-g&lt;/code&gt; flag, making them accessible from any directory on your system. Think of them as your development Swiss Army knife – CLI tools like &lt;code&gt;create-react-app&lt;/code&gt;, &lt;code&gt;nodemon&lt;/code&gt;, or &lt;code&gt;prettier&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To see what's installed globally at the top level:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm list &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nt"&gt;--depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;list&lt;/code&gt;: The primary command.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-g&lt;/code&gt;: Tells npm to look for global packages.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--depth=0&lt;/code&gt;: This is crucial! It limits the output to only the top-level packages, preventing a massive, nested tree of dependencies you likely don't care about at this level.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The output will be concise, showing just the main global packages you've installed.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Listing Local Project Packages: What Powers Your Current Project
&lt;/h4&gt;

&lt;p&gt;When you run &lt;code&gt;npm install&lt;/code&gt; without the &lt;code&gt;-g&lt;/code&gt; flag inside a project directory, packages are installed &lt;em&gt;locally&lt;/em&gt; within that project's &lt;code&gt;node_modules&lt;/code&gt; folder. These are the specific dependencies required for &lt;em&gt;that particular project&lt;/em&gt; to run.&lt;/p&gt;

&lt;p&gt;To see the top-level dependencies of your current project (those listed directly in your &lt;code&gt;package.json&lt;/code&gt; file):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm list &lt;span class="nt"&gt;--depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the absence of &lt;code&gt;-g&lt;/code&gt; here. This command assumes you're running it within your project's root directory. It will show you packages like &lt;code&gt;react&lt;/code&gt;, &lt;code&gt;express&lt;/code&gt;, &lt;code&gt;webpack&lt;/code&gt;, etc., without showing &lt;em&gt;their&lt;/em&gt; dependencies.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. The Full Local Dependency Tree: When You Need All the Details
&lt;/h4&gt;

&lt;p&gt;Sometimes, you &lt;em&gt;do&lt;/em&gt; need to see the entire dependency graph – including all the nested packages that your direct dependencies rely on. This can be useful for deep debugging or understanding the full footprint of your &lt;code&gt;node_modules&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;To see absolutely everything installed locally in your current project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fair warning:&lt;/strong&gt; For even moderately sized projects, the output of &lt;code&gt;npm list&lt;/code&gt; without &lt;code&gt;--depth=0&lt;/code&gt; can be incredibly long and overwhelming. Use this when you genuinely need to trace a specific sub-dependency.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Listing Packages in a Specific Directory (Optional)
&lt;/h4&gt;

&lt;p&gt;If you need to inspect packages in a project directory other than your current one, you can use the &lt;code&gt;--prefix&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm list &lt;span class="nt"&gt;--prefix&lt;/span&gt; /path/to/your/other/project &lt;span class="nt"&gt;--depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;/path/to/your/other/project&lt;/code&gt; with the actual path.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start with &lt;code&gt;--depth=0&lt;/code&gt;:&lt;/strong&gt; Most of the time, you only care about the top-level packages. This flag will save you a lot of scrolling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understand Global vs. Local:&lt;/strong&gt; Always be mindful of whether you're dealing with global tools or project-specific dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use &lt;code&gt;npm list&lt;/code&gt; for troubleshooting:&lt;/strong&gt; It's a powerful first step when something isn't quite right with your dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;npm list&lt;/code&gt; command, especially when combined with the &lt;code&gt;--depth=0&lt;/code&gt; flag, is an indispensable tool in any developer's arsenal. It empowers you to quickly understand your development environment, whether you're managing global utilities or navigating the intricate web of project dependencies. So go ahead, peek under the hood – you might be surprised by what you find!&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>npm</category>
      <category>node</category>
    </item>
    <item>
      <title>Getting Started with Angular: Installing and Creating Your First Project</title>
      <dc:creator>Manthan Ankolekar</dc:creator>
      <pubDate>Sat, 24 May 2025 05:45:00 +0000</pubDate>
      <link>https://dev.to/manthanank/getting-started-with-angular-installing-and-creating-your-first-project-2a16</link>
      <guid>https://dev.to/manthanank/getting-started-with-angular-installing-and-creating-your-first-project-2a16</guid>
      <description>&lt;p&gt;Angular is a powerful front-end framework for building web applications with TypeScript. Whether you're just starting out or returning to Angular after a break, setting up your development environment properly is the first step. This guide walks you through installing the Angular CLI and creating a new project tailored to your needs.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;The Angular CLI (Command Line Interface) is the recommended way to start Angular development. It provides commands to generate components, services, and modules, and to build, test, and serve your application.&lt;/p&gt;

&lt;p&gt;Install the Angular CLI globally using your preferred package manager:&lt;/p&gt;

&lt;h3&gt;
  
  
  Using npm:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using pnpm:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using yarn:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yarn global add @angular/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using bun:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bun &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Installing a Specific Version
&lt;/h2&gt;

&lt;p&gt;If you need a specific Angular CLI version, replace &lt;code&gt;version-number&lt;/code&gt; with your desired version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli@version-number
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Updating Angular CLI
&lt;/h2&gt;

&lt;p&gt;To update to the latest version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Verifying Installation
&lt;/h2&gt;

&lt;p&gt;To verify that the CLI is installed and to check the version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Creating a New Angular Project
&lt;/h2&gt;

&lt;p&gt;You can create a new Angular project using the &lt;code&gt;ng new&lt;/code&gt; command. Replace &lt;code&gt;[PROJECT NAME]&lt;/code&gt; with your desired project name.&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic command:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng new &lt;span class="o"&gt;[&lt;/span&gt;PROJECT NAME]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  With options:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Without standalone components&lt;/strong&gt; (Angular v17+):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ng new &lt;span class="o"&gt;[&lt;/span&gt;PROJECT NAME] &lt;span class="nt"&gt;--standalone&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Without routing&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ng new &lt;span class="o"&gt;[&lt;/span&gt;PROJECT NAME] &lt;span class="nt"&gt;--routing&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Without testing setup&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ng new &lt;span class="o"&gt;[&lt;/span&gt;PROJECT NAME] &lt;span class="nt"&gt;--skip-tests&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Without installing dependencies&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ng new &lt;span class="o"&gt;[&lt;/span&gt;PROJECT NAME] &lt;span class="nt"&gt;--skip-install&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Without Git initialization&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ng new &lt;span class="o"&gt;[&lt;/span&gt;PROJECT NAME] &lt;span class="nt"&gt;--skip-git&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;With experimental zoneless mode&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  ng new &lt;span class="o"&gt;[&lt;/span&gt;PROJECT NAME] &lt;span class="nt"&gt;--experimental-zoneless&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Standalone components were introduced in Angular v14 and became the default in Angular v17. Use the &lt;code&gt;--standalone&lt;/code&gt; flag to toggle this behavior during project creation.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Running Your Application
&lt;/h2&gt;

&lt;p&gt;After your project is created, navigate to the project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;PROJECT NAME]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then start the development server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open your browser and go to:&lt;br&gt;
&lt;a href="http://localhost:4200" rel="noopener noreferrer"&gt;http://localhost:4200&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;With the Angular CLI installed and your first project created, you're now ready to dive into building modern web applications with Angular. Stay tuned for more posts exploring components, routing, services, and beyond!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>angular</category>
    </item>
    <item>
      <title>Mastering Angular's New Control Flow with TypeScript Code Examples</title>
      <dc:creator>Manthan Ankolekar</dc:creator>
      <pubDate>Tue, 25 Mar 2025 05:09:21 +0000</pubDate>
      <link>https://dev.to/manthanank/mastering-angulars-new-control-flow-with-typescript-code-examples-1i96</link>
      <guid>https://dev.to/manthanank/mastering-angulars-new-control-flow-with-typescript-code-examples-1i96</guid>
      <description>&lt;p&gt;With the introduction of &lt;strong&gt;Angular v17&lt;/strong&gt;, the framework brings a &lt;strong&gt;new control flow syntax&lt;/strong&gt; that replaces &lt;code&gt;*ngIf&lt;/code&gt;, &lt;code&gt;*ngFor&lt;/code&gt;, and &lt;code&gt;*ngSwitch&lt;/code&gt; with &lt;strong&gt;@if, &lt;a class="mentioned-user" href="https://dev.to/for"&gt;@for&lt;/a&gt;, and &lt;a class="mentioned-user" href="https://dev.to/switch"&gt;@switch&lt;/a&gt;&lt;/strong&gt;. This makes Angular templates more readable, maintainable, and closer to JavaScript.  &lt;/p&gt;

&lt;p&gt;In this blog, we'll explore these features with practical &lt;strong&gt;TypeScript&lt;/strong&gt; examples and how to implement them in real-world Angular applications.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important Update&lt;/strong&gt;: The traditional structural directives (&lt;code&gt;*ngIf&lt;/code&gt;, &lt;code&gt;*ngFor&lt;/code&gt;, and &lt;code&gt;*ngSwitch&lt;/code&gt;) will be &lt;strong&gt;deprecated in Angular v20&lt;/strong&gt;. Now is the time to migrate your code to the new control flow syntax.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;1. Setting Up an Angular Component&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let's create a simple &lt;strong&gt;User Dashboard&lt;/strong&gt; component that displays user details, a list of orders, and order status.  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;✅ TypeScript (&lt;code&gt;dashboard.component.ts&lt;/code&gt;)&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Order&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shipped&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;delivered&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;isLoggedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Order&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="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;standalone&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="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dashboard.component.html&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;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DashboardComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;isLoggedIn&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="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;orders&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shipped&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;delivered&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;toggleUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;isLoggedIn&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="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;orders&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shipped&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;delivered&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;2. Using &lt;code&gt;@if&lt;/code&gt; for Conditional Rendering&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We'll use &lt;code&gt;@if&lt;/code&gt; to check if a user is logged in and display the appropriate UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;✅ Template (&lt;code&gt;dashboard.component.html&lt;/code&gt;)&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"toggleUser()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Toggle User&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

@if (user) {
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Welcome, {{ user.name }}!&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;You are logged in as {{ user.role }}.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
} @else {
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Please log in to access your dashboard.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;✨ Benefits of @if&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;No need for &lt;code&gt;&amp;lt;ng-container&amp;gt;&lt;/code&gt; wrappers.
&lt;/li&gt;
&lt;li&gt;Uses a syntax similar to JavaScript &lt;code&gt;if-else&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;3. Using &lt;code&gt;@for&lt;/code&gt; to Loop Through Orders&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We'll display a list of orders using &lt;code&gt;@for&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;✅ Template for &lt;a class="mentioned-user" href="https://dev.to/for"&gt;@for&lt;/a&gt;&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@if (user) {
    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Your Orders:&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
        @for (order of user.orders; track order.id) {
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Order #{{ order.id }} - {{ order.status }}&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        } @empty {
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;No orders found.&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        }
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;✨ Benefits of &lt;a class="mentioned-user" href="https://dev.to/for"&gt;@for&lt;/a&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;track order.id&lt;/code&gt; improves performance.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@empty&lt;/code&gt; handles cases when there are no items.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;4. Using &lt;code&gt;@switch&lt;/code&gt; to Handle Order Status&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We'll use &lt;code&gt;@switch&lt;/code&gt; to display different messages based on order status.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;✅ Template&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
    @for (order of user?.orders ?? []; track order.id) {
        &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
            Order #{{ order.id }} - 
            @switch (order.status) {
                @case ('pending') { &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-warning"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Pending&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt; }
                @case ('shipped') { &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-info"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Shipped&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt; }
                @case ('delivered') { &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-success"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Delivered&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt; }
                @default { &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-muted"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Unknown&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt; }
            }
        &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    }
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;✨ Benefits of &lt;a class="mentioned-user" href="https://dev.to/switch"&gt;@switch&lt;/a&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Eliminates excessive &lt;code&gt;*ngSwitchCase&lt;/code&gt; directives.
&lt;/li&gt;
&lt;li&gt;Closely mirrors JavaScript &lt;code&gt;switch&lt;/code&gt; syntax.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;5. Full Working Example&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;✅ Complete Implementation: TypeScript (&lt;code&gt;dashboard.component.ts&lt;/code&gt;)&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Order&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shipped&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;delivered&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="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;isLoggedIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Order&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="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-dashboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;standalone&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="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dashboard.component.html&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;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DashboardComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;isLoggedIn&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="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;orders&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shipped&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;delivered&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;toggleUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;isLoggedIn&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="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;orders&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="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;shipped&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;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;delivered&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;✅ HTML (&lt;code&gt;dashboard.component.html&lt;/code&gt;)&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"toggleUser()"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Toggle User&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

@if (user) {
    &lt;span class="nt"&gt;&amp;lt;h2&amp;gt;&lt;/span&gt;Welcome, {{ user.name }}!&lt;span class="nt"&gt;&amp;lt;/h2&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;You are logged in as {{ user.role }}.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Your Orders:&lt;span class="nt"&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
        @for (order of user.orders; track order.id) {
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
                Order #{{ order.id }} - 
                @switch (order.status) {
                    @case ('pending') { &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-warning"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Pending&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt; }
                    @case ('shipped') { &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-info"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Shipped&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt; }
                    @case ('delivered') { &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-success"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Delivered&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt; }
                    @default { &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-muted"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Unknown&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt; }
                }
            &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        } @empty {
            &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;No orders found.&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
        }
    &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
} @else {
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Please log in to access your dashboard.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;6. Key Takeaways&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;✅ &lt;strong&gt;More Readable&lt;/strong&gt; – No more &lt;code&gt;*&lt;/code&gt; prefixes, making it JavaScript-like.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Less Boilerplate&lt;/strong&gt; – No need for extra &lt;code&gt;&amp;lt;ng-container&amp;gt;&lt;/code&gt; elements.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Better Performance&lt;/strong&gt; – Faster change detection and rendering.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Improved Debugging&lt;/strong&gt; – Clearer syntax simplifies troubleshooting.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Future-Proof&lt;/strong&gt; – Legacy syntax will be deprecated in Angular v20.&lt;/p&gt;


&lt;h2&gt;
  
  
  &lt;strong&gt;7. How to Enable the New Control Flow?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The new control flow is &lt;strong&gt;enabled by default&lt;/strong&gt; in Angular v17+. If you're using an older version, upgrade your Angular project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng update @angular/core @angular/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng generate @angular/core:control-flow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once updated, you can start using &lt;code&gt;@if&lt;/code&gt;, &lt;code&gt;@for&lt;/code&gt;, and &lt;code&gt;@switch&lt;/code&gt; in your templates.  &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Final Thoughts&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Angular's &lt;strong&gt;new control flow&lt;/strong&gt; is a game-changer, making templates &lt;strong&gt;cleaner, more readable, and more efficient&lt;/strong&gt;. With the upcoming deprecation of the old syntax in Angular v20, now is the perfect time to embrace these changes. Whether you're working on a small project or a large enterprise app, adopting this syntax will make your Angular development experience &lt;strong&gt;smoother and faster&lt;/strong&gt; while ensuring your codebase stays current with Angular's evolution.  &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;8. Exploring the Code&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Visit the &lt;a href="https://github.com/manthanank/angular-examples/tree/new-control-flow" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; to explore the code in detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;9. Live Demo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Check out the working example on &lt;a href="https://stackblitz.com/edit/stackblitz-starters-eq3uyo6r" rel="noopener noreferrer"&gt;StackBlitz&lt;/a&gt;  &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;10. Additional Resources&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://angular.dev/guide/templates/control-flow" rel="noopener noreferrer"&gt;Angular New Control Flow Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to leave comments or questions below! 👋&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>beginners</category>
      <category>angular</category>
    </item>
  </channel>
</rss>
