<?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: Prashant Patil</title>
    <description>The latest articles on DEV Community by Prashant Patil (@prashant_patil_49).</description>
    <link>https://dev.to/prashant_patil_49</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3837365%2F9ba3206b-ef1f-45e9-b5f4-cd1973f436a6.png</url>
      <title>DEV Community: Prashant Patil</title>
      <link>https://dev.to/prashant_patil_49</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/prashant_patil_49"/>
    <language>en</language>
    <item>
      <title>My First Open Source Contribution That Got Merged</title>
      <dc:creator>Prashant Patil</dc:creator>
      <pubDate>Wed, 15 Jul 2026 13:17:03 +0000</pubDate>
      <link>https://dev.to/prashant_patil_49/my-first-open-source-contribution-that-got-merged-4jc9</link>
      <guid>https://dev.to/prashant_patil_49/my-first-open-source-contribution-that-got-merged-4jc9</guid>
      <description>&lt;p&gt;While searching for my first software engineering role, I wanted experience beyond personal projects. I wanted to understand how real production software is built and maintained.&lt;/p&gt;

&lt;p&gt;Open source was the best place to learn, so I started looking for a project where I could make a meaningful contribution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding the Right Opportunity
&lt;/h2&gt;

&lt;p&gt;Like many beginners, I first targeted highly active repositories. One of them was cal.com, where I raised an issue and implemented the fix immediately.&lt;/p&gt;

&lt;p&gt;Unfortunately, another contributor's pull request was merged before mine.&lt;/p&gt;

&lt;p&gt;Instead of getting discouraged, I decided to look for an issue that better matched my experience and where I could genuinely help.&lt;/p&gt;

&lt;p&gt;Eventually, I found the Express Release Status website, a React-based project. One issue caught my attention because it had been opened by one of the maintainers and the requirements were clear.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working on the Issue
&lt;/h2&gt;

&lt;p&gt;The task was simple on paper: make the Express release timeline clickable.&lt;/p&gt;

&lt;p&gt;Instead of jumping straight into coding, I first explored the project structure to understand where the timeline was being rendered.&lt;/p&gt;

&lt;p&gt;After locating the relevant React component, I looked at how navigation was already implemented across the application. Rather than introducing a different approach, I wanted my solution to match the existing codebase.&lt;/p&gt;

&lt;p&gt;I found that the project used React Router's &lt;code&gt;Link&lt;/code&gt; component for internal navigation.&lt;/p&gt;

&lt;p&gt;So instead of creating a custom solution or using HTML anchor tags, I followed the same pattern.&lt;/p&gt;

&lt;p&gt;The actual code change was surprisingly small. I modified only the lines responsible for rendering the release timeline and wrapped them with the existing routing component.&lt;/p&gt;

&lt;p&gt;By keeping the change minimal and focused on the issue, the pull request stayed clean and easy to review.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practices I Followed
&lt;/h2&gt;

&lt;p&gt;This contribution taught me a few habits that I still follow today:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand the codebase before writing code.&lt;/li&gt;
&lt;li&gt;Follow the project's existing patterns instead of introducing your own.&lt;/li&gt;
&lt;li&gt;Change only what is necessary.&lt;/li&gt;
&lt;li&gt;Keep pull requests focused on a single issue.&lt;/li&gt;
&lt;li&gt;Respect the review process and respond to maintainer feedback promptly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting the Pull Request Merged
&lt;/h2&gt;

&lt;p&gt;After opening the pull request, the maintainers requested verification before merging it, which I completed.&lt;/p&gt;

&lt;p&gt;The pull request then remained open for almost 2–3 months.&lt;/p&gt;

&lt;p&gt;During that time, I politely emailed the maintainers to follow up. They responded kindly, and after the review process was complete, my pull request was finally merged.&lt;/p&gt;

&lt;p&gt;Seeing that merge notification felt incredibly rewarding because it was my first contribution to a real production project.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;This experience taught me that open source isn't about writing the most code—it's about writing the right code.&lt;/p&gt;

&lt;p&gt;Small, focused pull requests are easier to review than large ones.&lt;/p&gt;

&lt;p&gt;Reading and understanding an existing codebase is just as important as writing new features.&lt;/p&gt;

&lt;p&gt;Most importantly, patience matters. Reviews can take weeks or even months, but persistence pays off.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>github</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How To Implemented Email OTP Verification in Web Application</title>
      <dc:creator>Prashant Patil</dc:creator>
      <pubDate>Sat, 04 Jul 2026 09:32:34 +0000</pubDate>
      <link>https://dev.to/prashant_patil_49/how-to-implemented-email-otp-verification-in-web-application-45nf</link>
      <guid>https://dev.to/prashant_patil_49/how-to-implemented-email-otp-verification-in-web-application-45nf</guid>
      <description>&lt;p&gt;Email verification has become a standard feature in modern web applications. Whether you're building an e-commerce platform, a social media application, or a job portal, verifying a user's email helps ensure that accounts belong to real users while reducing spam and fake registrations.&lt;/p&gt;

&lt;p&gt;During one of my MERN stack projects, I wanted to implement email-based OTP verification. Initially, I had no idea where to start. I knew the feature was important, but I wasn't sure how production applications handled it. So, I spent time researching different approaches, reading documentation, and even asking AI how large companies implement email verification systems.&lt;/p&gt;

&lt;p&gt;This article summarizes what I learned and explains the approach I found easiest to implement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Different Ways to Send OTP Emails
&lt;/h2&gt;

&lt;p&gt;There are several ways to send verification emails from your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Nodemailer (The Simplest for MERN Applications)
&lt;/h3&gt;

&lt;p&gt;If you're using Node.js, Nodemailer is one of the easiest libraries to integrate. It allows your backend to send emails through providers like Gmail, Outlook, or SMTP servers with very little setup.&lt;/p&gt;

&lt;p&gt;For personal projects, learning, or small-scale applications, this is an excellent choice because it requires minimal configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Email Service Providers (Recommended for Production)
&lt;/h3&gt;

&lt;p&gt;As I researched further, I found that most large companies don't send emails directly using Gmail. Instead, they use dedicated email delivery services such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Amazon SES&lt;/li&gt;
&lt;li&gt;SendGrid&lt;/li&gt;
&lt;li&gt;Mailgun&lt;/li&gt;
&lt;li&gt;Postmark&lt;/li&gt;
&lt;li&gt;Brevo (formerly Sendinblue)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These services provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better email deliverability&lt;/li&gt;
&lt;li&gt;Higher sending limits&lt;/li&gt;
&lt;li&gt;Analytics&lt;/li&gt;
&lt;li&gt;Bounce handling&lt;/li&gt;
&lt;li&gt;Spam protection&lt;/li&gt;
&lt;li&gt;Improved reliability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many of these services also provide Node.js SDKs, making integration straightforward.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. SMTP Servers
&lt;/h3&gt;

&lt;p&gt;Another option is connecting your application directly to an SMTP server. Many hosting providers and organizations provide SMTP credentials that applications can use to send emails.&lt;/p&gt;

&lt;p&gt;This approach offers more control but usually requires additional configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Chose Nodemailer
&lt;/h2&gt;

&lt;p&gt;Since my project was built using the MERN stack, I found Nodemailer to be the simplest solution.&lt;/p&gt;

&lt;p&gt;It integrates seamlessly with Express.js and only requires a few lines of code to send emails. The extensive documentation and large community also make troubleshooting much easier.&lt;/p&gt;

&lt;p&gt;For learning purposes and personal projects, I believe this is one of the best ways to understand how email verification works before moving on to enterprise-grade services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Google Account and Getting Credentials
&lt;/h2&gt;

&lt;p&gt;To use Gmail with Nodemailer, you'll first need a Google account.&lt;/p&gt;

&lt;p&gt;Instead of using your normal Gmail password, Google recommends creating an App Password.&lt;/p&gt;

&lt;p&gt;The general process is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create or use an existing Google account.&lt;/li&gt;
&lt;li&gt;Enable 2-Step Verification on the account.&lt;/li&gt;
&lt;li&gt;Navigate to your Google Account security settings.&lt;/li&gt;
&lt;li&gt;Generate an App Password.&lt;/li&gt;
&lt;li&gt;Use the generated email address and App Password inside your Node.js application.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These credentials allow Nodemailer to securely authenticate with Gmail without exposing your actual account password.&lt;/p&gt;

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

&lt;p&gt;While designing the User model, I added a simple field:&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;isEmailVerified&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&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="k"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This field determines whether the user has successfully verified their email address.&lt;/p&gt;

&lt;p&gt;Whenever a new account is created, this value remains &lt;code&gt;false&lt;/code&gt; until the OTP verification process is completed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Login Flow
&lt;/h2&gt;

&lt;p&gt;One thing I wanted to avoid was allowing unverified users to access the application.&lt;/p&gt;

&lt;p&gt;The login flow works like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User enters email and password.&lt;/li&gt;
&lt;li&gt;Validate the credentials.&lt;/li&gt;
&lt;li&gt;Check the &lt;code&gt;isEmailVerified&lt;/code&gt; field.&lt;/li&gt;
&lt;li&gt;If the value is &lt;code&gt;true&lt;/code&gt;, allow login.&lt;/li&gt;
&lt;li&gt;If the value is &lt;code&gt;false&lt;/code&gt;, redirect the user to the OTP verification page.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;On the OTP page, the user's email is already pre-filled, making the process faster and more user-friendly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sending the OTP
&lt;/h2&gt;

&lt;p&gt;When the user clicks the &lt;strong&gt;Send OTP&lt;/strong&gt; button:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate a random 6-digit OTP.&lt;/li&gt;
&lt;li&gt;Set an expiration time (typically 5–10 minutes).&lt;/li&gt;
&lt;li&gt;Send the OTP to the registered email using Nodemailer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates a smooth experience while preventing unnecessary emails from being sent automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Never Store OTPs in Plain Text
&lt;/h2&gt;

&lt;p&gt;One important lesson I learned is that OTPs should never be stored directly in the database.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Hash the OTP using a secure hashing algorithm such as bcrypt.&lt;/li&gt;
&lt;li&gt;Store only the hashed version.&lt;/li&gt;
&lt;li&gt;Keep an expiration timestamp.&lt;/li&gt;
&lt;li&gt;Delete or invalidate the OTP after successful verification or expiry.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures that even if someone gains database access, they cannot view users' OTPs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verifying the OTP
&lt;/h2&gt;

&lt;p&gt;Once the user enters the OTP:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieve the stored hashed OTP.&lt;/li&gt;
&lt;li&gt;Compare the entered OTP with the hashed value.&lt;/li&gt;
&lt;li&gt;Verify that the OTP hasn't expired.&lt;/li&gt;
&lt;li&gt;If the OTP matches:

&lt;ul&gt;
&lt;li&gt;Update &lt;code&gt;isEmailVerified&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Remove the stored OTP.&lt;/li&gt;
&lt;li&gt;Allow the user to continue using the application.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If the OTP is incorrect or expired, ask the user to request a new OTP.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Additional Best Practices
&lt;/h2&gt;

&lt;p&gt;While implementing the feature, I also discovered several practices commonly used in production applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Limit the number of OTP requests within a certain time window.&lt;/li&gt;
&lt;li&gt;Add a cooldown (for example, 30–60 seconds) before allowing another OTP request.&lt;/li&gt;
&lt;li&gt;Set OTP expiration to 5–10 minutes.&lt;/li&gt;
&lt;li&gt;Limit incorrect verification attempts.&lt;/li&gt;
&lt;li&gt;Log verification events for auditing.&lt;/li&gt;
&lt;li&gt;Use HTTPS to protect data during transmission.&lt;/li&gt;
&lt;li&gt;Prevent brute-force attacks with rate limiting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These measures improve both security and user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;Before implementing this feature, I assumed email verification would be difficult. After researching multiple approaches, I realized the overall concept is actually straightforward once you understand the authentication flow.&lt;/p&gt;

&lt;p&gt;For my MERN stack application, Nodemailer turned out to be the easiest solution because it integrates naturally with Node.js and Express. Later, I also learned that larger companies usually rely on dedicated email services like Amazon SES or SendGrid for better scalability and reliability.&lt;/p&gt;

&lt;p&gt;If you're building your first full-stack application, implementing email OTP verification is a great way to strengthen your understanding of authentication, backend development, database design, and application security. Once you understand the fundamentals, transitioning to enterprise-grade email providers becomes much easier.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Building GitHub-Inspired Version Control and Forking Without Duplicating Project Files</title>
      <dc:creator>Prashant Patil</dc:creator>
      <pubDate>Thu, 18 Jun 2026 03:21:44 +0000</pubDate>
      <link>https://dev.to/prashant_patil_49/building-github-inspired-version-control-and-forking-without-duplicating-project-files-5aap</link>
      <guid>https://dev.to/prashant_patil_49/building-github-inspired-version-control-and-forking-without-duplicating-project-files-5aap</guid>
      <description>&lt;p&gt;One of the challenges I faced while building my LaTeX Writer project was implementing version control and project forking in a storage-efficient way.&lt;/p&gt;

&lt;p&gt;A typical LaTeX project contains multiple files. Even a simple project usually has a "main.tex" file, bibliography files, images, style files, and other supporting documents. If I stored a complete copy of every file for every version or fork, storage requirements would grow rapidly.&lt;/p&gt;

&lt;p&gt;Imagine a project with four files and ten versions. Storing the entire project for every version would mean storing the same files repeatedly, even when only one line changed. Forking would create an even bigger problem because every fork would require another complete copy of the project.&lt;/p&gt;

&lt;p&gt;Instead of accepting this inefficiency, I started researching how large platforms solve the same problem. GitHub was the obvious inspiration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning from GitHub
&lt;/h3&gt;

&lt;p&gt;GitHub does not store a complete copy of a repository every time a change is made. Instead, it stores content separately and uses references to connect files, commits, and repositories.&lt;/p&gt;

&lt;p&gt;This idea became the foundation for my own implementation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Structure
&lt;/h3&gt;

&lt;p&gt;Whenever a new project is created, a default file called "main.tex" is generated automatically.&lt;/p&gt;

&lt;p&gt;The project itself does not directly contain file contents. Instead, it stores metadata such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project ID&lt;/li&gt;
&lt;li&gt;Owner ID&lt;/li&gt;
&lt;li&gt;Root Folder ID&lt;/li&gt;
&lt;li&gt;File References&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each file also has its own metadata record containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File ID&lt;/li&gt;
&lt;li&gt;File Name&lt;/li&gt;
&lt;li&gt;Blob ID&lt;/li&gt;
&lt;li&gt;Project ID&lt;/li&gt;
&lt;li&gt;Owner ID&lt;/li&gt;
&lt;li&gt;Folder ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The actual content is not stored inside the file metadata.&lt;/p&gt;

&lt;p&gt;Instead, the content lives inside a separate entity called a Blob.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loading a Project
&lt;/h3&gt;

&lt;p&gt;When the editor loads a project, it reconstructs the directory structure using metadata.&lt;/p&gt;

&lt;h3&gt;
  
  
  The process works like this:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Retrieve the project's Root Folder ID.&lt;/li&gt;
&lt;li&gt;Find all folders belonging to that folder hierarchy.&lt;/li&gt;
&lt;li&gt;Find all files belonging to each folder.&lt;/li&gt;
&lt;li&gt;Build the directory tree for the frontend.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because files and folders are stored independently, the entire project structure can be recreated efficiently without duplicating data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Blob-Based Content Storage
&lt;/h3&gt;

&lt;p&gt;The most important optimization is the Blob system.&lt;/p&gt;

&lt;p&gt;A Blob represents the actual content of a file.&lt;/p&gt;

&lt;h3&gt;
  
  
  When a user edits a file:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;The content is hashed.&lt;/li&gt;
&lt;li&gt;A unique Blob ID is generated.&lt;/li&gt;
&lt;li&gt;If a Blob with identical content already exists, the existing Blob is reused.&lt;/li&gt;
&lt;li&gt;The file metadata simply points to the appropriate Blob.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This means identical file contents are stored only once, regardless of how many files, versions, or forks reference them.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Forking Works
&lt;/h3&gt;

&lt;p&gt;Forking was designed with the same principle.&lt;/p&gt;

&lt;h3&gt;
  
  
  When a user forks a project:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A new Project ID is created.&lt;/li&gt;
&lt;li&gt;New file metadata records are created.&lt;/li&gt;
&lt;li&gt;New folder metadata records are created.&lt;/li&gt;
&lt;li&gt;Ownership information changes to the new user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, the file content is not copied.&lt;/p&gt;

&lt;p&gt;The new file metadata points to the exact same Blob IDs as the original project.&lt;/p&gt;

&lt;p&gt;As a result, a fork initially consumes very little additional storage because only metadata is duplicated.&lt;/p&gt;

&lt;p&gt;What Happens When a Fork Is Edited?&lt;/p&gt;

&lt;p&gt;Suppose User A creates a project and User B forks it.&lt;/p&gt;

&lt;p&gt;Initially, both projects reference the same Blobs.&lt;/p&gt;

&lt;h3&gt;
  
  
  If User B edits a file:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;The updated content is hashed.&lt;/li&gt;
&lt;li&gt;The system checks whether a Blob with that content already exists.&lt;/li&gt;
&lt;li&gt;If it exists, the existing Blob is reused.&lt;/li&gt;
&lt;li&gt;If it does not exist, a new Blob is created.&lt;/li&gt;
&lt;li&gt;User B's file metadata is updated to point to the new Blob.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The original project remains unchanged because its file metadata still points to the old Blob.&lt;/p&gt;

&lt;p&gt;This creates behavior similar to Git's object storage model while keeping storage usage minimal.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Result
&lt;/h3&gt;

&lt;p&gt;By separating metadata from content and introducing Blob-based storage, I achieved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Efficient version management&lt;/li&gt;
&lt;li&gt;Storage-friendly project forking&lt;/li&gt;
&lt;li&gt;Content deduplication&lt;/li&gt;
&lt;li&gt;Faster project cloning&lt;/li&gt;
&lt;li&gt;Reduced database growth&lt;/li&gt;
&lt;li&gt;GitHub-inspired architecture without implementing Git itself&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of storing the same file hundreds of times, the system stores content once and uses references everywhere else.&lt;/p&gt;

&lt;p&gt;This approach allows the platform to scale much more efficiently while supporting features like version history, project cloning, and collaborative workflows.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>javascript</category>
      <category>github</category>
    </item>
    <item>
      <title>How Google AI Mode Works (Simple Explanation)</title>
      <dc:creator>Prashant Patil</dc:creator>
      <pubDate>Tue, 12 May 2026 15:34:30 +0000</pubDate>
      <link>https://dev.to/prashant_patil_49/how-google-ai-mode-works-simple-explanation-1fk4</link>
      <guid>https://dev.to/prashant_patil_49/how-google-ai-mode-works-simple-explanation-1fk4</guid>
      <description>&lt;p&gt;Google AI Mode is a new way of searching on Google where Artificial Intelligence (AI) gives direct answers instead of only showing a list of websites.&lt;/p&gt;

&lt;p&gt;Normally, when you search something on Google, you see many blue links. You open different websites to find your answer. But in AI Mode, Google itself reads information from many websites and creates a smart answer for you.&lt;/p&gt;

&lt;p&gt;It works more like talking to an AI assistant.&lt;/p&gt;

&lt;p&gt;For example, if you search:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Best laptop for coding under ₹60,000”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI Mode may directly give:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Recommended laptops&lt;/li&gt;
&lt;li&gt;Features comparison&lt;/li&gt;
&lt;li&gt;Pros and cons&lt;/li&gt;
&lt;li&gt;Buying suggestions&lt;/li&gt;
&lt;li&gt;Links to websites for more details&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of making you open 10 different pages.&lt;/p&gt;

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

&lt;h1&gt;
  
  
  How Google AI Mode Generates Results
&lt;/h1&gt;

&lt;p&gt;Google AI Mode works in multiple steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Understand Your Question
&lt;/h2&gt;

&lt;p&gt;The AI first tries to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What you are asking&lt;/li&gt;
&lt;li&gt;Your intent&lt;/li&gt;
&lt;li&gt;Important keywords&lt;/li&gt;
&lt;li&gt;Context of the question&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For example:&lt;/strong&gt;&lt;br&gt;
"Best protein for skinny beginners"&lt;/p&gt;

&lt;p&gt;Google understands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User is probably trying to gain muscle&lt;/li&gt;
&lt;li&gt;User is beginner&lt;/li&gt;
&lt;li&gt;User wants protein recommendations&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 2: Search the Internet
&lt;/h2&gt;

&lt;p&gt;Then Google searches across:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Websites&lt;/li&gt;
&lt;li&gt;Blogs&lt;/li&gt;
&lt;li&gt;Forums&lt;/li&gt;
&lt;li&gt;Product pages&lt;/li&gt;
&lt;li&gt;Reviews&lt;/li&gt;
&lt;li&gt;News articles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Google already has one of the biggest search indexes in the world. AI Mode uses this huge database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: AI Reads and Combines Information
&lt;/h2&gt;

&lt;p&gt;The AI model reads information from multiple sources and combines them into a single answer.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Website A&lt;/li&gt;
&lt;li&gt;Website B&lt;/li&gt;
&lt;li&gt;Website C&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It creates one summarized response.&lt;/p&gt;

&lt;p&gt;This is called:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI-generated summary&lt;/li&gt;
&lt;li&gt;AI overview&lt;/li&gt;
&lt;li&gt;Generative search result&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 4: Ranking and Verification
&lt;/h2&gt;

&lt;p&gt;Google still uses its traditional ranking systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Website authority&lt;/li&gt;
&lt;li&gt;Quality&lt;/li&gt;
&lt;li&gt;Trustworthiness&lt;/li&gt;
&lt;li&gt;Freshness of content&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is important because AI alone can sometimes generate wrong information.&lt;/p&gt;

&lt;p&gt;So Google combines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traditional search ranking&lt;/li&gt;
&lt;li&gt;AI language models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Showing Follow-Up Suggestions
&lt;/h2&gt;

&lt;p&gt;After giving an answer, AI Mode often suggests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Related questions&lt;/li&gt;
&lt;li&gt;Follow-up searches&lt;/li&gt;
&lt;li&gt;Product comparisons&lt;/li&gt;
&lt;li&gt;Deeper explanations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps the search conversational.&lt;/p&gt;




&lt;h2&gt;
  
  
  How is Google AI Mode Different From Gemini?
&lt;/h2&gt;

&lt;p&gt;Many people think Google AI Mode and Google Gemini are the same thing. But they are different.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Google AI Mode&lt;/th&gt;
&lt;th&gt;Gemini&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Built inside Google Search&lt;/td&gt;
&lt;td&gt;Separate AI assistant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Focused on web search&lt;/td&gt;
&lt;td&gt;Focused on conversation and tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uses live search results heavily&lt;/td&gt;
&lt;td&gt;Can answer from training knowledge too&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shows website links with answers&lt;/td&gt;
&lt;td&gt;More chatbot-style&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Better for finding information online&lt;/td&gt;
&lt;td&gt;Better for brainstorming, writing, coding&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Difference Between Google AI Mode and Other AI Chatbots
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Google AI Mode vs ChatGPT
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Google AI Mode&lt;/th&gt;
&lt;th&gt;ChatGPT&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Search-focused&lt;/td&gt;
&lt;td&gt;Conversation-focused&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uses real-time web search&lt;/td&gt;
&lt;td&gt;Depends on tools/web access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for finding latest info&lt;/td&gt;
&lt;td&gt;Best for explanations and creativity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gives source links&lt;/td&gt;
&lt;td&gt;Can explain concepts deeply&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Google AI Mode vs Perplexity
&lt;/h3&gt;

&lt;p&gt;Perplexity AI is actually very similar to Google AI Mode.&lt;/p&gt;

&lt;p&gt;Both:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search the web&lt;/li&gt;
&lt;li&gt;Summarize information&lt;/li&gt;
&lt;li&gt;Give AI answers&lt;/li&gt;
&lt;li&gt;Show sources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The biggest difference is:&lt;/strong&gt;&lt;br&gt;
Google combines AI with its existing search engine, while Perplexity is built mainly as an AI-first search platform.&lt;/p&gt;




&lt;h2&gt;
  
  
  Is Google AI Mode Always Correct?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;No.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes AI Mode can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Misunderstand questions&lt;/li&gt;
&lt;li&gt;Give outdated information&lt;/li&gt;
&lt;li&gt;Mix incorrect facts&lt;/li&gt;
&lt;li&gt;Create "hallucinations" (fake information)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is why Google still provides website links below the AI answer.&lt;/p&gt;

&lt;p&gt;You should still verify important information, especially for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Medical advice&lt;/li&gt;
&lt;li&gt;Financial decisions&lt;/li&gt;
&lt;li&gt;Legal topics&lt;/li&gt;
&lt;li&gt;Technical accuracy&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Google AI Mode is basically Google Search mixed with AI conversation.&lt;/p&gt;

&lt;p&gt;Instead of only showing websites, it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Understands your question&lt;/li&gt;
&lt;li&gt;Searches the web&lt;/li&gt;
&lt;li&gt;Reads multiple sources&lt;/li&gt;
&lt;li&gt;Creates a summarized answer&lt;/li&gt;
&lt;li&gt;Lets you continue asking questions&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It is making search faster and more interactive.&lt;/p&gt;

&lt;p&gt;But it is not replacing websites completely. It still depends heavily on information created by websites and content creators across the internet.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>google</category>
      <category>learning</category>
    </item>
    <item>
      <title>The SQL Mistake Everyone Makes: Writing vs Execution Order</title>
      <dc:creator>Prashant Patil</dc:creator>
      <pubDate>Mon, 06 Apr 2026 18:25:40 +0000</pubDate>
      <link>https://dev.to/prashant_patil_49/the-sql-mistake-everyone-makes-writing-vs-execution-order-40lf</link>
      <guid>https://dev.to/prashant_patil_49/the-sql-mistake-everyone-makes-writing-vs-execution-order-40lf</guid>
      <description>&lt;p&gt;When I first started learning SQL, my approach was very straightforward. I would begin with the &lt;code&gt;SELECT&lt;/code&gt; statement, list the columns I wanted, add the &lt;code&gt;FROM&lt;/code&gt; clause, and then shape the query based on the problem.&lt;/p&gt;

&lt;p&gt;This worked well for simple queries. However, as problems became more complex, I repeatedly ran into the same issue: I had to rewrite queries from scratch because of small mistakes. This wasted time and slowed down my progress.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;The core issue was simple — I was writing SQL in the order it appears, not in the order it executes.&lt;/p&gt;

&lt;p&gt;Because of this, I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Applied filters at the wrong stage&lt;/li&gt;
&lt;li&gt;Misused aggregate functions&lt;/li&gt;
&lt;li&gt;Got incorrect results&lt;/li&gt;
&lt;li&gt;Rewrote queries multiple times&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Turning Point
&lt;/h2&gt;

&lt;p&gt;While watching a developer solve multiple SQL problems, I noticed a pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They rarely rewrote queries&lt;/li&gt;
&lt;li&gt;They followed a structured flow&lt;/li&gt;
&lt;li&gt;They thought in terms of execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is when I realized:&lt;/p&gt;

&lt;p&gt;SQL is not executed in the order we write it.&lt;/p&gt;

&lt;p&gt;Understanding this changed everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  SQL Execution Order
&lt;/h2&gt;

&lt;p&gt;The actual execution order of SQL is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;FROM&lt;/li&gt;
&lt;li&gt;WHERE&lt;/li&gt;
&lt;li&gt;GROUP BY&lt;/li&gt;
&lt;li&gt;HAVING&lt;/li&gt;
&lt;li&gt;SELECT&lt;/li&gt;
&lt;li&gt;DISTINCT&lt;/li&gt;
&lt;li&gt;ORDER BY&lt;/li&gt;
&lt;li&gt;LIMIT&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each step transforms the data before passing it to the next stage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Clause Breakdown
&lt;/h2&gt;

&lt;h3&gt;
  
  
  FROM
&lt;/h3&gt;

&lt;p&gt;Selects the base table and performs joins.&lt;/p&gt;

&lt;h3&gt;
  
  
  WHERE
&lt;/h3&gt;

&lt;p&gt;Filters rows before grouping.&lt;/p&gt;

&lt;h3&gt;
  
  
  GROUP BY
&lt;/h3&gt;

&lt;p&gt;Groups rows based on column values.&lt;/p&gt;

&lt;h3&gt;
  
  
  HAVING
&lt;/h3&gt;

&lt;p&gt;Filters grouped data.&lt;/p&gt;

&lt;h3&gt;
  
  
  SELECT
&lt;/h3&gt;

&lt;p&gt;Chooses columns and applies calculations.&lt;/p&gt;

&lt;h3&gt;
  
  
  DISTINCT
&lt;/h3&gt;

&lt;p&gt;Removes duplicates.&lt;/p&gt;

&lt;h3&gt;
  
  
  ORDER BY
&lt;/h3&gt;

&lt;p&gt;Sorts results.&lt;/p&gt;

&lt;h3&gt;
  
  
  LIMIT
&lt;/h3&gt;

&lt;p&gt;Restricts number of rows returned.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Table: orders
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;order_id&lt;/th&gt;
&lt;th&gt;customer&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;th&gt;city&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;Pune&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;200&lt;/td&gt;
&lt;td&gt;Mumbai&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;150&lt;/td&gt;
&lt;td&gt;Pune&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;td&gt;Delhi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;B&lt;/td&gt;
&lt;td&gt;250&lt;/td&gt;
&lt;td&gt;Mumbai&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Problem
&lt;/h3&gt;

&lt;p&gt;Find total order amount per city where total &amp;gt; 200 and sort descending.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_amount&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;amount&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;total_amount&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Execution Walkthrough
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: FROM
&lt;/h3&gt;

&lt;p&gt;All rows are selected.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: WHERE
&lt;/h3&gt;

&lt;p&gt;Filter &lt;code&gt;amount &amp;gt; 100&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Remaining rows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mumbai: 200, 250&lt;/li&gt;
&lt;li&gt;Pune: 150&lt;/li&gt;
&lt;li&gt;Delhi: 300&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: GROUP BY
&lt;/h3&gt;

&lt;p&gt;Groups formed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mumbai&lt;/li&gt;
&lt;li&gt;Pune&lt;/li&gt;
&lt;li&gt;Delhi&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: HAVING
&lt;/h3&gt;

&lt;p&gt;Filter groups:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mumbai (450) -&amp;gt; keep&lt;/li&gt;
&lt;li&gt;Pune (150) -&amp;gt; remove&lt;/li&gt;
&lt;li&gt;Delhi (300) -&amp;gt; keep&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 5: SELECT
&lt;/h3&gt;

&lt;p&gt;Result:&lt;br&gt;
| city   | total_amount |&lt;br&gt;
|--------|-------------|&lt;br&gt;
| Mumbai | 450         |&lt;br&gt;
| Delhi  | 300         |&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: ORDER BY
&lt;/h3&gt;

&lt;p&gt;Sorted descending:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mumbai&lt;/li&gt;
&lt;li&gt;Delhi&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaway
&lt;/h2&gt;

&lt;p&gt;Do not think in terms of writing SQL.&lt;/p&gt;

&lt;p&gt;Think in terms of execution.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Reduce errors&lt;/li&gt;
&lt;li&gt;Improve speed&lt;/li&gt;
&lt;li&gt;Help solve complex queries&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Understanding SQL execution order is a fundamental skill. Once you start thinking in execution steps instead of syntax order, your ability to write efficient and correct queries improves significantly.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>dbms</category>
      <category>database</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Why Deleting `node_modules` Takes Forever on Windows</title>
      <dc:creator>Prashant Patil</dc:creator>
      <pubDate>Sat, 21 Mar 2026 16:56:18 +0000</pubDate>
      <link>https://dev.to/prashant_patil_49/why-deleting-nodemodules-takes-forever-on-windows-1h73</link>
      <guid>https://dev.to/prashant_patil_49/why-deleting-nodemodules-takes-forever-on-windows-1h73</guid>
      <description>&lt;p&gt;A few days ago, I was deleting a project when something unexpectedly frustrating happened — it took way too long.&lt;/p&gt;

&lt;p&gt;Not seconds. Not even a minute. It just kept going.&lt;/p&gt;

&lt;p&gt;If you’ve worked with JavaScript projects, you already know the culprit: &lt;code&gt;node_modules&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That moment got me thinking. Since I’ve been studying operating system fundamentals, I wanted to understand what’s actually happening behind the scenes. Why does a simple delete operation take so long?&lt;/p&gt;

&lt;p&gt;So I went down the rabbit hole — digging through documentation, GitHub discussions, and system-level explanations. I even explored how Linux handles file deletion to compare behaviors.&lt;/p&gt;

&lt;p&gt;Here’s what I found.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Reason Isn’t Just “Too Many Files”
&lt;/h2&gt;

&lt;p&gt;Yes, &lt;code&gt;node_modules&lt;/code&gt; contains thousands of files — sometimes hundreds of thousands.&lt;/p&gt;

&lt;p&gt;But that’s only part of the story.&lt;/p&gt;

&lt;p&gt;The real reason deletion is slow on Windows comes down to how the operating system handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;File system operations
&lt;/li&gt;
&lt;li&gt;Security checks
&lt;/li&gt;
&lt;li&gt;Path resolution
&lt;/li&gt;
&lt;li&gt;File locking
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s break it down.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Windows Deletes Files One by One
&lt;/h2&gt;

&lt;p&gt;Unlike what many people assume, Windows does not delete folders in bulk.&lt;/p&gt;

&lt;p&gt;Instead, it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Traverses every directory
&lt;/li&gt;
&lt;li&gt;Deletes each file individually
&lt;/li&gt;
&lt;li&gt;Updates metadata for every operation
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now imagine doing that for 100,000+ files.&lt;/p&gt;

&lt;p&gt;That alone creates noticeable delay.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. File Locking Adds Extra Overhead
&lt;/h2&gt;

&lt;p&gt;Windows uses a strict file locking mechanism.&lt;/p&gt;

&lt;p&gt;Before deleting a file, it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checks whether the file is in use
&lt;/li&gt;
&lt;li&gt;Verifies parent directories
&lt;/li&gt;
&lt;li&gt;Temporarily locks parts of the directory structure
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If anything is being accessed — even indirectly — the system slows down or retries the operation.&lt;/p&gt;

&lt;p&gt;This adds friction, especially in deeply nested folders like &lt;code&gt;node_modules&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Windows Defender Is the Biggest Bottleneck
&lt;/h2&gt;

&lt;p&gt;This is where most of the time actually goes.&lt;/p&gt;

&lt;p&gt;Windows Defender scans files not just when they’re created or opened — but also when they’re deleted.&lt;/p&gt;

&lt;p&gt;That might sound unnecessary, but there’s a reason.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Create harmful files
&lt;/li&gt;
&lt;li&gt;Execute them
&lt;/li&gt;
&lt;li&gt;Delete them quickly to avoid detection
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To prevent this, Windows scans files during deletion as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In many cases, 60–70% of the total deletion time is spent on Defender scans alone.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Long File Paths Make Things Worse
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;node_modules&lt;/code&gt; often contains deeply nested dependencies.&lt;/p&gt;

&lt;p&gt;This leads to extremely long file paths.&lt;/p&gt;

&lt;p&gt;Windows has historically had a path length limit (~260 characters). Even though modern systems support longer paths, many tools still struggle with them.&lt;/p&gt;

&lt;p&gt;When paths exceed limits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Operations can fail
&lt;/li&gt;
&lt;li&gt;Windows retries them silently
&lt;/li&gt;
&lt;li&gt;Additional time is wasted
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  5. NTFS File System Overhead
&lt;/h2&gt;

&lt;p&gt;Windows uses the NTFS file system, which prioritizes reliability and consistency.&lt;/p&gt;

&lt;p&gt;For every file deletion, NTFS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Updates logs
&lt;/li&gt;
&lt;li&gt;Maintains metadata
&lt;/li&gt;
&lt;li&gt;Ensures file system integrity
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doing this for thousands of files significantly slows things down.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Linux and macOS Handle It Differently
&lt;/h2&gt;

&lt;p&gt;Unix-based systems take a much simpler and faster approach.&lt;/p&gt;

&lt;p&gt;They:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid heavy antivirus scanning during deletion
&lt;/li&gt;
&lt;li&gt;Use more efficient file unlinking mechanisms
&lt;/li&gt;
&lt;li&gt;Have fewer restrictions on file paths
&lt;/li&gt;
&lt;li&gt;Use a more flexible file locking model
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is a noticeable difference in performance.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quick Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Windows (NTFS)&lt;/th&gt;
&lt;th&gt;Linux/macOS (ext4/APFS)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;File Deletion&lt;/td&gt;
&lt;td&gt;File-by-file with checks&lt;/td&gt;
&lt;td&gt;Faster unlinking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Antivirus&lt;/td&gt;
&lt;td&gt;Scans during deletion&lt;/td&gt;
&lt;td&gt;Typically no scan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Path Limits&lt;/td&gt;
&lt;td&gt;Historically restrictive&lt;/td&gt;
&lt;td&gt;More flexible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File Locking&lt;/td&gt;
&lt;td&gt;Strict&lt;/td&gt;
&lt;td&gt;More relaxed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance on &lt;code&gt;node_modules&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Slow&lt;/td&gt;
&lt;td&gt;Significantly faster&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Why Windows Prioritizes Safety
&lt;/h2&gt;

&lt;p&gt;At this point, it’s fair to ask: why does Windows do all this?&lt;/p&gt;

&lt;p&gt;The answer is simple — security.&lt;/p&gt;

&lt;p&gt;Without these checks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Malware could create and delete files instantly
&lt;/li&gt;
&lt;li&gt;Those files might never be scanned
&lt;/li&gt;
&lt;li&gt;The system could be compromised silently
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So while it feels inefficient, it’s a deliberate design decision.&lt;/p&gt;




&lt;h2&gt;
  
  
  Can You Speed It Up?
&lt;/h2&gt;

&lt;p&gt;Yes — but every shortcut comes with trade-offs.&lt;/p&gt;

&lt;p&gt;Some practical options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use tools like &lt;code&gt;rimraf&lt;/code&gt; for faster deletion
&lt;/li&gt;
&lt;li&gt;Enable long path support in Windows
&lt;/li&gt;
&lt;li&gt;Use WSL (Windows Subsystem for Linux) for development workflows
&lt;/li&gt;
&lt;li&gt;Avoid reinstalling dependencies unnecessarily
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also disable real-time antivirus scanning temporarily, but that introduces risk and isn’t advisable for regular use.&lt;/p&gt;




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

&lt;p&gt;Deleting &lt;code&gt;node_modules&lt;/code&gt; slowly on Windows isn’t a bug — it’s the result of intentional system design.&lt;/p&gt;

&lt;p&gt;Windows favors safety and control.&lt;br&gt;&lt;br&gt;
Unix-based systems favor speed and simplicity.&lt;/p&gt;

&lt;p&gt;Once you understand that trade-off, the behavior makes a lot more sense — even if it’s still frustrating.&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>discuss</category>
      <category>learning</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
