<?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: Mayur Pawar</title>
    <description>The latest articles on DEV Community by Mayur Pawar (@mayur_pawar_9b0a092ca0f41).</description>
    <link>https://dev.to/mayur_pawar_9b0a092ca0f41</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%2F2260781%2Fbf71f355-3d9b-4c1a-ba66-1d1d230e32ad.png</url>
      <title>DEV Community: Mayur Pawar</title>
      <link>https://dev.to/mayur_pawar_9b0a092ca0f41</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mayur_pawar_9b0a092ca0f41"/>
    <language>en</language>
    <item>
      <title>Stop Paying for Authentication: Migrate from Clerk &amp; Google OAuth to Open Source</title>
      <dc:creator>Mayur Pawar</dc:creator>
      <pubDate>Fri, 17 Jul 2026 13:38:50 +0000</pubDate>
      <link>https://dev.to/mayur_pawar_9b0a092ca0f41/replacing-google-oauth-clerk-with-open-source-authentication-a-simple-step-by-step-guide-487a</link>
      <guid>https://dev.to/mayur_pawar_9b0a092ca0f41/replacing-google-oauth-clerk-with-open-source-authentication-a-simple-step-by-step-guide-487a</guid>
      <description>&lt;p&gt;Authentication is one of the first things developers add to an application. Today, many teams use services like Google OAuth, Clerk, Auth0, or Firebase Authentication because they are easy to integrate and handle most of the security for you.&lt;/p&gt;

&lt;p&gt;But what happens if you want complete control over your authentication system? Maybe you want to avoid vendor lock-in, reduce costs, or host everything yourself.&lt;/p&gt;

&lt;p&gt;The good news is that you don't need to build authentication from scratch. You can replace managed authentication platforms with open source identity providers that offer the same core features.&lt;/p&gt;

&lt;p&gt;In this article, we'll understand how Google OAuth and Clerk work, and how we can replace them with open source implementations in simple words.&lt;/p&gt;




&lt;h1&gt;
  
  
  How Authentication Works Today
&lt;/h1&gt;

&lt;p&gt;Let's imagine a user wants to log into your application.&lt;/p&gt;

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

&lt;p&gt;Here's what happens behind the scenes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The user clicks &lt;strong&gt;Sign in&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Google or Clerk displays the login page.&lt;/li&gt;
&lt;li&gt;The user enters their credentials.&lt;/li&gt;
&lt;li&gt;The authentication provider verifies them.&lt;/li&gt;
&lt;li&gt;A JWT (JSON Web Token) is generated.&lt;/li&gt;
&lt;li&gt;The frontend sends this token with every API request.&lt;/li&gt;
&lt;li&gt;The backend verifies the token before allowing access.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notice something important:&lt;/p&gt;

&lt;p&gt;Your backend never checks the user's password.&lt;/p&gt;

&lt;p&gt;Google or Clerk does that for you.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Problem
&lt;/h1&gt;

&lt;p&gt;Managed authentication services are great, but they come with trade-offs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monthly subscription costs&lt;/li&gt;
&lt;li&gt;Vendor lock-in&lt;/li&gt;
&lt;li&gt;Limited customization&lt;/li&gt;
&lt;li&gt;Your authentication depends on a third-party service&lt;/li&gt;
&lt;li&gt;Less control over user management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As your application grows, you might want to host authentication yourself.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Idea Behind Replacing Them
&lt;/h1&gt;

&lt;p&gt;Many developers think they need to rebuild OAuth.&lt;/p&gt;

&lt;p&gt;You don't.&lt;/p&gt;

&lt;p&gt;OAuth is a standard.&lt;/p&gt;

&lt;p&gt;What you're actually replacing is the &lt;strong&gt;Identity Provider&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of asking Google or Clerk to verify users, you'll run your own authentication server.&lt;/p&gt;

&lt;p&gt;That's it.&lt;/p&gt;

&lt;h1&gt;
  
  
  The New Architecture
&lt;/h1&gt;

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

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

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

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

&lt;p&gt;The flow stays almost exactly the same.&lt;/p&gt;

&lt;p&gt;Only the service performing authentication changes.&lt;/p&gt;

&lt;h1&gt;
  
  
  Which Open Source Tools Can Replace Clerk?
&lt;/h1&gt;

&lt;p&gt;Some popular options are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keycloak&lt;/li&gt;
&lt;li&gt;Authentik&lt;/li&gt;
&lt;li&gt;Ory Kratos&lt;/li&gt;
&lt;li&gt;Zitadel&lt;/li&gt;
&lt;li&gt;SuperTokens Community Edition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Among these, Keycloak is one of the most mature and widely used solutions.&lt;/p&gt;

&lt;p&gt;It already supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OAuth 2.0&lt;/li&gt;
&lt;li&gt;OpenID Connect&lt;/li&gt;
&lt;li&gt;JWT Tokens&lt;/li&gt;
&lt;li&gt;User Management&lt;/li&gt;
&lt;li&gt;Role-Based Access Control&lt;/li&gt;
&lt;li&gt;Multi-Factor Authentication&lt;/li&gt;
&lt;li&gt;Social Login&lt;/li&gt;
&lt;li&gt;Single Sign-On (SSO)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Step 1: Deploy Your Authentication Server
&lt;/h1&gt;

&lt;p&gt;Install an authentication server like Keycloak.&lt;/p&gt;

&lt;p&gt;Instead of relying on Google, Keycloak becomes responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Managing users&lt;/li&gt;
&lt;li&gt;Managing passwords&lt;/li&gt;
&lt;li&gt;Creating sessions&lt;/li&gt;
&lt;li&gt;Generating JWT tokens&lt;/li&gt;
&lt;li&gt;Handling login and logout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it as your own private version of Google Login.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 2: Store Users Yourself
&lt;/h1&gt;

&lt;p&gt;Instead of Google storing user accounts, your authentication server stores them.&lt;/p&gt;

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

&lt;p&gt;Passwords are never stored as plain text.&lt;/p&gt;

&lt;p&gt;They are securely hashed using algorithms like bcrypt or Argon2.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 3: User Logs In
&lt;/h1&gt;

&lt;p&gt;The user enters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Email&lt;/li&gt;
&lt;li&gt;Password&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The frontend sends these credentials to Keycloak.&lt;/p&gt;

&lt;p&gt;Keycloak checks the credentials.&lt;/p&gt;

&lt;p&gt;If they're correct, it generates a JWT token.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 4: Return the JWT
&lt;/h1&gt;

&lt;p&gt;Keycloak sends a JWT token back to the frontend.&lt;/p&gt;

&lt;p&gt;The frontend stores it securely.&lt;/p&gt;

&lt;p&gt;Now the user is authenticated.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5: Call Protected APIs
&lt;/h1&gt;

&lt;p&gt;Whenever the frontend calls your backend, it includes the JWT.&lt;br&gt;
&lt;/p&gt;

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

Authorization: Bearer &amp;lt;JWT_TOKEN&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Step 6: Verify the Token
&lt;/h1&gt;

&lt;p&gt;The backend checks whether the JWT is valid.&lt;/p&gt;

&lt;p&gt;If it is valid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allow the request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If it is invalid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Return 401 Unauthorized.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is exactly how Google OAuth and Clerk work.&lt;/p&gt;

&lt;p&gt;The only difference is that your own server issued the token.&lt;/p&gt;

&lt;h1&gt;
  
  
  Before vs After
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Before
&lt;/h3&gt;

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

&lt;h3&gt;
  
  
  After
&lt;/h3&gt;

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

&lt;p&gt;Nothing changes for your backend except who issues the token.&lt;/p&gt;




&lt;h1&gt;
  
  
  Migration Steps
&lt;/h1&gt;

&lt;p&gt;If you're moving away from Clerk or Google OAuth, your migration looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deploy Keycloak (or another open source identity provider).&lt;/li&gt;
&lt;li&gt;Create your application (client) inside Keycloak.&lt;/li&gt;
&lt;li&gt;Configure login, registration, and roles.&lt;/li&gt;
&lt;li&gt;Update the frontend to authenticate with Keycloak.&lt;/li&gt;
&lt;li&gt;Update the backend to verify JWTs issued by Keycloak.&lt;/li&gt;
&lt;li&gt;Test login, logout, and protected routes.&lt;/li&gt;
&lt;li&gt;Remove Clerk or Google OAuth from your application.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Benefits of Self-Hosted Authentication
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;No vendor lock-in&lt;/li&gt;
&lt;li&gt;Lower long-term costs&lt;/li&gt;
&lt;li&gt;Full control over user data&lt;/li&gt;
&lt;li&gt;Custom authentication workflows&lt;/li&gt;
&lt;li&gt;Support for OAuth 2.0 and OpenID Connect&lt;/li&gt;
&lt;li&gt;Enterprise-ready features like SSO, MFA, and RBAC&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Challenges
&lt;/h1&gt;

&lt;p&gt;Self-hosting also comes with responsibilities.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You must maintain the authentication server.&lt;/li&gt;
&lt;li&gt;You need to install security updates.&lt;/li&gt;
&lt;li&gt;You are responsible for backups and monitoring.&lt;/li&gt;
&lt;li&gt;Initial setup takes more effort than using a managed service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For small projects, managed authentication may still be the better choice.&lt;/p&gt;

&lt;p&gt;For larger applications or organizations that need complete control, open source identity providers can be an excellent solution.&lt;/p&gt;

&lt;h1&gt;
  
  
  Final Thoughts
&lt;/h1&gt;

&lt;p&gt;Replacing Google OAuth or Clerk doesn't mean replacing OAuth itself.&lt;/p&gt;

&lt;p&gt;You're simply replacing the service that proves a user's identity.&lt;/p&gt;

&lt;p&gt;Instead of trusting a third-party provider, you run your own identity server while continuing to use industry standards like OAuth 2.0, OpenID Connect, and JWT.&lt;/p&gt;

&lt;p&gt;The overall login flow remains almost identical, but you gain full ownership of your authentication infrastructure.&lt;/p&gt;

&lt;p&gt;If you're building products that require flexibility, customization, or long-term control, open source authentication is definitely worth exploring.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
      <category>security</category>
      <category>programming</category>
    </item>
    <item>
      <title>I Was Tired of Broken Deployments, So I Built This CLI Tool</title>
      <dc:creator>Mayur Pawar</dc:creator>
      <pubDate>Tue, 26 May 2026 16:43:22 +0000</pubDate>
      <link>https://dev.to/mayur_pawar_9b0a092ca0f41/i-was-tired-of-broken-deployments-so-i-built-this-cli-tool-2dc3</link>
      <guid>https://dev.to/mayur_pawar_9b0a092ca0f41/i-was-tired-of-broken-deployments-so-i-built-this-cli-tool-2dc3</guid>
      <description>&lt;h2&gt;
  
  
  I Built an npm CLI Tool That Checks If Your Project Is Deployment Ready
&lt;/h2&gt;

&lt;p&gt;Deployments often fail for the smallest reasons.&lt;/p&gt;

&lt;p&gt;A missing &lt;code&gt;.env&lt;/code&gt; file.&lt;br&gt;&lt;br&gt;
A forgotten build script.&lt;br&gt;&lt;br&gt;
A missing Dockerfile.&lt;br&gt;&lt;br&gt;
An incomplete Vercel configuration.&lt;br&gt;&lt;br&gt;
Or accidentally exposing secrets inside the project.&lt;/p&gt;

&lt;p&gt;Most developers discover these issues only after pushing to production.&lt;/p&gt;

&lt;p&gt;After running into these problems repeatedly while building projects, I decided to build a tool that checks deployment readiness before deployment even happens.&lt;/p&gt;

&lt;p&gt;So I built:&lt;/p&gt;
&lt;h2&gt;
  
  
  🚀 mayur-deploy-ready
&lt;/h2&gt;

&lt;p&gt;A zero-config CLI tool that analyzes your project, detects deployment issues, scans for security risks, validates platform configurations, and even auto-generates missing deployment files.&lt;/p&gt;


&lt;h2&gt;
  
  
  📦 What is mayur-deploy-ready?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;mayur-deploy-ready&lt;/code&gt; is a deployment readiness analyzer for Node.js projects.&lt;/p&gt;

&lt;p&gt;It performs automated checks across multiple categories including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;package configuration&lt;/li&gt;
&lt;li&gt;Docker setup&lt;/li&gt;
&lt;li&gt;security validation&lt;/li&gt;
&lt;li&gt;framework detection&lt;/li&gt;
&lt;li&gt;platform deployment configs&lt;/li&gt;
&lt;li&gt;CI/CD readiness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Catch deployment issues locally before they break production.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  ⚡ Installation
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Global Install
&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; mayur-deploy-ready
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Run the Tool
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mayur-deploy-ready
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🎯 Example Output
&lt;/h2&gt;

&lt;p&gt;When you run the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mayur-deploy-ready
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get a deployment analysis report like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;━━━━━━━━━━━━━━━━━━━━━━
🚀 DEPLOY READY
━━━━━━━━━━━━━━━━━━━━━━

✔ package.json found
⚠ Build script missing
⚠ Dockerfile missing
⚠ .env missing

━━━━━━━━━━━━━━━━━━━━━━
📊 Deployment Score: 75/100
━━━━━━━━━━━━━━━━━━━━━━

🟡 Needs Attention
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tool also provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;suggestions&lt;/li&gt;
&lt;li&gt;categorized scoring&lt;/li&gt;
&lt;li&gt;warnings&lt;/li&gt;
&lt;li&gt;deployment readiness status&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔥 Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ Weighted Deployment Scoring
&lt;/h3&gt;

&lt;p&gt;One of the most interesting parts of the project was designing the scoring architecture.&lt;/p&gt;

&lt;p&gt;The tool calculates a deployment readiness score out of 100 using weighted categories like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;PACKAGE: 20/20
SCRIPTS: 10/20
SECURITY: 25/25
DOCKER: 5/10
FRAMEWORK: 0/10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of only showing warnings, this gives developers a much clearer picture of how deployment-ready their project actually is.&lt;/p&gt;

&lt;p&gt;The scoring system categorizes projects into:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Score&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;85–100&lt;/td&gt;
&lt;td&gt;🟢 Production Ready&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;60–84&lt;/td&gt;
&lt;td&gt;🟡 Needs Attention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0–59&lt;/td&gt;
&lt;td&gt;🔴 Unsafe Deployment&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  🔐 Advanced Security Scanning
&lt;/h2&gt;

&lt;p&gt;I wanted the tool to do more than just check missing files.&lt;/p&gt;

&lt;p&gt;So I implemented recursive security scanning that detects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAI API keys&lt;/li&gt;
&lt;li&gt;MongoDB URIs&lt;/li&gt;
&lt;li&gt;JWT secrets&lt;/li&gt;
&lt;li&gt;AWS access keys&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;⚠ Potential OpenAI API Key detected &lt;span class="k"&gt;in &lt;/span&gt;src/test-secret.js
⚠ Potential MongoDB URI detected &lt;span class="k"&gt;in &lt;/span&gt;config/api.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While building this feature, I learned that security scanning is much harder than it initially looks.&lt;/p&gt;

&lt;p&gt;At first, the scanner even detected secrets inside the tool’s own internal files.&lt;/p&gt;

&lt;p&gt;That forced me to redesign the scanner architecture with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;configurable ignore paths&lt;/li&gt;
&lt;li&gt;recursive traversal&lt;/li&gt;
&lt;li&gt;extension filtering&lt;/li&gt;
&lt;li&gt;smarter regex matching&lt;/li&gt;
&lt;li&gt;production-style exclusions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ended up becoming one of the most educational parts of the project.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 Auto Fix Mode
&lt;/h2&gt;

&lt;p&gt;Another feature I really enjoyed building was automatic repair mode.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mayur-deploy-ready fix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tool can automatically generate missing deployment files such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.gitignore&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.dockerignore&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Dockerfile&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.env.example&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vercel.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;railway.json&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This helps developers bootstrap deployment configurations much faster.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤖 JSON Mode for CI/CD
&lt;/h2&gt;

&lt;p&gt;I also added structured JSON output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mayur-deploy-ready &lt;span class="nt"&gt;--json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the tool easy to integrate into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Actions&lt;/li&gt;
&lt;li&gt;Jenkins&lt;/li&gt;
&lt;li&gt;GitLab CI&lt;/li&gt;
&lt;li&gt;dashboards&lt;/li&gt;
&lt;li&gt;automation scripts&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"score"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"stats"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"passed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"warnings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"errors"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚙️ CI/CD Support
&lt;/h2&gt;

&lt;p&gt;The tool also supports CI mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mayur-deploy-ready &lt;span class="nt"&gt;--ci&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit codes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0&lt;/code&gt; → deployment ready&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; → deployment unsafe&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows deployments to fail automatically inside CI pipelines if critical deployment issues are detected.&lt;/p&gt;

&lt;p&gt;I also added example integrations for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Actions&lt;/li&gt;
&lt;li&gt;GitLab CI&lt;/li&gt;
&lt;li&gt;Jenkins&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;inside the README documentation.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 What I Learned Building This
&lt;/h2&gt;

&lt;p&gt;This project taught me much more than I expected.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. CLI Development Is Different From Web Development
&lt;/h3&gt;

&lt;p&gt;Building CLI tools requires thinking about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;terminal UX&lt;/li&gt;
&lt;li&gt;output formatting&lt;/li&gt;
&lt;li&gt;developer experience&lt;/li&gt;
&lt;li&gt;command parsing&lt;/li&gt;
&lt;li&gt;readable logs&lt;/li&gt;
&lt;li&gt;automation compatibility&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  2. npm Publishing Has Real-World Edge Cases
&lt;/h3&gt;

&lt;p&gt;While publishing the package, I ran into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;npm authentication issues&lt;/li&gt;
&lt;li&gt;2FA requirements&lt;/li&gt;
&lt;li&gt;package publishing permissions&lt;/li&gt;
&lt;li&gt;README caching&lt;/li&gt;
&lt;li&gt;Shields.io badge caching&lt;/li&gt;
&lt;li&gt;npm session expiration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are things you rarely encounter while building normal frontend projects.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Security Tooling Requires Careful Design
&lt;/h3&gt;

&lt;p&gt;The security scanner taught me an important lesson:&lt;/p&gt;

&lt;p&gt;Naive scanning creates too many false positives.&lt;/p&gt;

&lt;p&gt;To make the tool useful, I had to redesign the scanner with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ignore systems&lt;/li&gt;
&lt;li&gt;configurable exclusions&lt;/li&gt;
&lt;li&gt;smarter recursion&lt;/li&gt;
&lt;li&gt;safer matching logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That experience gave me a much better understanding of developer tooling architecture.&lt;/p&gt;




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

&lt;p&gt;The project is organized into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;checks/&lt;/code&gt; → validation logic&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fixes/&lt;/code&gt; → auto-generated deployment fixes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;utils/&lt;/code&gt; → scoring, logging, stats&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;frameworks/&lt;/code&gt; → framework-specific validations&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;bin/index.js&lt;/code&gt; → CLI orchestration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The architecture became much larger than I originally planned, but it also helped me understand how production-style CLI tools are structured.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Open Source
&lt;/h2&gt;

&lt;p&gt;The project is fully open source.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;https://github.com/mayurCoder2004/mayur-deploy-ready
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;https://www.npmjs.com/package/mayur-deploy-ready
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;This started as a small utility to help me avoid deployment mistakes.&lt;/p&gt;

&lt;p&gt;But while building it, I learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CLI architecture&lt;/li&gt;
&lt;li&gt;npm publishing workflows&lt;/li&gt;
&lt;li&gt;deployment tooling&lt;/li&gt;
&lt;li&gt;security scanning&lt;/li&gt;
&lt;li&gt;scoring systems&lt;/li&gt;
&lt;li&gt;CI/CD integration&lt;/li&gt;
&lt;li&gt;developer experience design&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Honestly, this became one of the most educational projects I’ve built so far.&lt;/p&gt;

&lt;p&gt;If you try it out, I’d genuinely love feedback from other developers 🚀&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
    <item>
      <title>How I Built ChefMate — An AI Recipe App for Hostel &amp; PG Students</title>
      <dc:creator>Mayur Pawar</dc:creator>
      <pubDate>Wed, 06 May 2026 15:59:53 +0000</pubDate>
      <link>https://dev.to/mayur_pawar_9b0a092ca0f41/how-i-built-chefmate-an-ai-recipe-app-for-hostel-pg-students-15co</link>
      <guid>https://dev.to/mayur_pawar_9b0a092ca0f41/how-i-built-chefmate-an-ai-recipe-app-for-hostel-pg-students-15co</guid>
      <description>&lt;p&gt;Most recipe apps assume you already have a full kitchen.&lt;/p&gt;

&lt;p&gt;But during college and hostel life, the reality is usually:&lt;br&gt;
onion + potato + maggi + random masalas 😭&lt;/p&gt;

&lt;p&gt;That simple problem became the idea behind ChefMate.&lt;/p&gt;

&lt;p&gt;I wanted to build something where users could simply select the ingredients they already had available and instantly generate quick Indian-style recipes instead of endlessly searching YouTube or recipe blogs. &lt;/p&gt;




&lt;h1&gt;
  
  
  🚀 What is ChefMate?
&lt;/h1&gt;

&lt;p&gt;ChefMate is a full-stack AI-powered recipe and meal planning platform built using the MERN stack.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;generate recipes using available ingredients&lt;/li&gt;
&lt;li&gt;use a guided Cook Mode&lt;/li&gt;
&lt;li&gt;save recipes&lt;/li&gt;
&lt;li&gt;create meal plans&lt;/li&gt;
&lt;li&gt;share recipes using public links&lt;/li&gt;
&lt;li&gt;browse additional recipes using TheMealDB API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The focus was making the experience simple and practical for students, hostel residents, and bachelors living alone. &lt;/p&gt;




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

&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;Tailwind CSS&lt;/li&gt;
&lt;li&gt;React Router&lt;/li&gt;
&lt;li&gt;Axios&lt;/li&gt;
&lt;li&gt;React Hot Toast&lt;/li&gt;
&lt;li&gt;React GA4&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Backend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Express&lt;/li&gt;
&lt;li&gt;MongoDB&lt;/li&gt;
&lt;li&gt;Mongoose&lt;/li&gt;
&lt;li&gt;JWT Authentication&lt;/li&gt;
&lt;li&gt;Express Rate Limit&lt;/li&gt;
&lt;li&gt;Zod Validation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI &amp;amp; APIs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;OpenRouter API&lt;/li&gt;
&lt;li&gt;Gemini / Llama / Mistral models&lt;/li&gt;
&lt;li&gt;TheMealDB API&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  ✨ Features I Added
&lt;/h1&gt;

&lt;h2&gt;
  
  
  🤖 AI Recipe Generator
&lt;/h2&gt;

&lt;p&gt;Users select ingredients and preferences like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;vegetarian/vegan&lt;/li&gt;
&lt;li&gt;cooking time&lt;/li&gt;
&lt;li&gt;dietary preferences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The app then generates structured recipes with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ingredients&lt;/li&gt;
&lt;li&gt;cooking steps&lt;/li&gt;
&lt;li&gt;health benefits&lt;/li&gt;
&lt;li&gt;estimated cooking time&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🍳 Cook Mode
&lt;/h2&gt;

&lt;p&gt;One feature I personally liked building was Cook Mode.&lt;/p&gt;

&lt;p&gt;Instead of showing a giant recipe paragraph, the app guides users step-by-step while cooking.&lt;/p&gt;

&lt;p&gt;I also added:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;progress tracking&lt;/li&gt;
&lt;li&gt;timers&lt;/li&gt;
&lt;li&gt;step navigation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;to make the cooking experience smoother. &lt;/p&gt;




&lt;h2&gt;
  
  
  📅 AI Meal Planner
&lt;/h2&gt;

&lt;p&gt;Users can generate meal plans for multiple days based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;calorie goals&lt;/li&gt;
&lt;li&gt;diet preferences&lt;/li&gt;
&lt;li&gt;number of days&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔗 Shareable Recipes
&lt;/h2&gt;

&lt;p&gt;Users can generate public recipe links and share them directly through WhatsApp or browser sharing APIs.&lt;/p&gt;

&lt;p&gt;Shared recipes can be opened without login. &lt;/p&gt;




&lt;h1&gt;
  
  
  ⚡ Biggest Challenges
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Making AI responses consistent
&lt;/h2&gt;

&lt;p&gt;LLM outputs are unpredictable.&lt;/p&gt;

&lt;p&gt;Sometimes responses came as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSON&lt;/li&gt;
&lt;li&gt;markdown&lt;/li&gt;
&lt;li&gt;incomplete text&lt;/li&gt;
&lt;li&gt;broken formatting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I had to build normalization and validation logic to structure responses properly. &lt;/p&gt;




&lt;h2&gt;
  
  
  2. UI/UX Problems
&lt;/h2&gt;

&lt;p&gt;One thing I learned quickly:&lt;br&gt;
good functionality alone is not enough.&lt;/p&gt;

&lt;p&gt;Early feedback made me realize:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the UI felt too “AI-generated”&lt;/li&gt;
&lt;li&gt;layouts were inconsistent&lt;/li&gt;
&lt;li&gt;some flows were confusing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I spent a lot of time refining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;spacing&lt;/li&gt;
&lt;li&gt;typography&lt;/li&gt;
&lt;li&gt;visual hierarchy&lt;/li&gt;
&lt;li&gt;loading states&lt;/li&gt;
&lt;li&gt;mobile responsiveness&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Public Feedback &amp;amp; Distribution
&lt;/h2&gt;

&lt;p&gt;I recently started sharing the project publicly and learned that distribution is honestly harder than coding sometimes 😭&lt;/p&gt;

&lt;p&gt;Posting on communities taught me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;how people perceive AI products&lt;/li&gt;
&lt;li&gt;how important positioning is&lt;/li&gt;
&lt;li&gt;how to communicate projects naturally instead of sounding overly promotional&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That was a surprisingly valuable learning experience.&lt;/p&gt;




&lt;h1&gt;
  
  
  🔒 Security Improvements
&lt;/h1&gt;

&lt;p&gt;One important issue I discovered after feedback:&lt;br&gt;
the AI endpoints initially had no proper rate limiting.&lt;/p&gt;

&lt;p&gt;Since LLM APIs cost credits, users could theoretically spam requests.&lt;/p&gt;

&lt;p&gt;I fixed this using Express Rate Limit to protect expensive endpoints. &lt;/p&gt;




&lt;h1&gt;
  
  
  📈 What I Learned
&lt;/h1&gt;

&lt;p&gt;Building ChefMate taught me much more than just coding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;shipping real products&lt;/li&gt;
&lt;li&gt;handling user feedback&lt;/li&gt;
&lt;li&gt;improving UX&lt;/li&gt;
&lt;li&gt;API security&lt;/li&gt;
&lt;li&gt;analytics integration&lt;/li&gt;
&lt;li&gt;authentication flows&lt;/li&gt;
&lt;li&gt;real-world deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also made me realize:&lt;br&gt;
building something usable is much harder than just making something functional.&lt;/p&gt;




&lt;h1&gt;
  
  
  🔮 Future Plans
&lt;/h1&gt;

&lt;p&gt;Some things I’d like to improve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;recipe images/videos&lt;/li&gt;
&lt;li&gt;grocery list generation&lt;/li&gt;
&lt;li&gt;better onboarding&lt;/li&gt;
&lt;li&gt;stronger personalization&lt;/li&gt;
&lt;li&gt;social/community features&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  🌐 Live Demo
&lt;/h1&gt;

&lt;p&gt;ChefMate:&lt;br&gt;
&lt;a href="https://chefmate-frontend.vercel.app" rel="noopener noreferrer"&gt;https://chefmate-frontend.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;GitHub:&lt;br&gt;
&lt;a href="https://github.com/mayurCoder2004/chefmate" rel="noopener noreferrer"&gt;https://github.com/mayurCoder2004/chefmate&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Would genuinely love feedback from other developers/builders on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UI/UX&lt;/li&gt;
&lt;li&gt;product direction&lt;/li&gt;
&lt;li&gt;architecture&lt;/li&gt;
&lt;li&gt;ideas for improvement 🙌&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>react</category>
      <category>node</category>
    </item>
    <item>
      <title>Still Feel Alone Online? We Built Something to Fix That</title>
      <dc:creator>Mayur Pawar</dc:creator>
      <pubDate>Wed, 01 Apr 2026 20:00:21 +0000</pubDate>
      <link>https://dev.to/mayur_pawar_9b0a092ca0f41/still-feel-alone-online-we-built-something-to-fix-that-3l2c</link>
      <guid>https://dev.to/mayur_pawar_9b0a092ca0f41/still-feel-alone-online-we-built-something-to-fix-that-3l2c</guid>
      <description>&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%2Ftr2gv7p63tc9vu8tbqw2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftr2gv7p63tc9vu8tbqw2.png" alt=" " width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  We Spent Months Building a Virtual Home for Couples. Here's the Honest Story.
&lt;/h1&gt;

&lt;p&gt;You can be online all day and still feel completely alone.&lt;/p&gt;

&lt;p&gt;Texts. Calls. Notifications. A green dot next to someone's name.&lt;/p&gt;

&lt;p&gt;None of it makes you feel like you're actually &lt;em&gt;with&lt;/em&gt; them.&lt;/p&gt;

&lt;p&gt;That gap — between being connected and feeling &lt;em&gt;present&lt;/em&gt; — is what led us to build &lt;strong&gt;TogetherUs&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is It?
&lt;/h2&gt;

&lt;p&gt;TogetherUs is a shared 2D pixel-art virtual world built specifically for couples in long-distance relationships.&lt;/p&gt;

&lt;p&gt;Think of it as your own &lt;strong&gt;private digital apartment&lt;/strong&gt; — a cozy space where you and your partner can hang out, watch movies, listen to music, study together, or simply sit in a garden and talk face to face.&lt;/p&gt;

&lt;p&gt;No tasks. No agenda. No performance. Just presence.&lt;/p&gt;

&lt;p&gt;You create a private room, share a code with your partner, and step into a charming pixel world together. As your customizable avatars explore the space, a Picture-in-Picture video call keeps you visually connected the whole time.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Zones Inside
&lt;/h2&gt;

&lt;p&gt;This isn't just a chat room. Every area of the world serves a different kind of togetherness:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎥 Movie Zone&lt;/strong&gt; — Watch YouTube videos in perfect sync. Shared play/pause, seek, speed control, and quality selection up to 4K. An elastic sync system with heartbeat keeps both of you on the exact same frame even across different network speeds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎵 Music Zone&lt;/strong&gt; — A synchronized jukebox powered by YouTube Music. Search any song, get real-time autocomplete, browse recommendations, and like tracks. No account needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🎮 Game Zone&lt;/strong&gt; — Play multiplayer games together via an integrated arcade. Smash Karts, Mini Golf, Chess, and more — no extra installs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📚 Study Zone&lt;/strong&gt; — A co-working space with a synchronized Pomodoro timer, a collaborative whiteboard (Excalidraw), and a shared PDF viewer. For the couples who grind together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🌿 Garden Area&lt;/strong&gt; — Step in here and the PiP video expands to full screen. Just you two, face to face. Built for the conversations that matter.&lt;/p&gt;




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

&lt;p&gt;Here's what's actually running under the hood:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Frontend:&lt;/strong&gt; React 18 + Vite, Phaser 3 for the 2D pixel world, Zustand for state, Framer Motion for animations, Socket.IO client, WebRTC via Simple-Peer for video, Excalidraw for the whiteboard, TailwindCSS&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backend:&lt;/strong&gt; Node.js + Express, Socket.IO for real-time events, PostgreSQL 16, Redis 7 for sessions and pub/sub, Firebase Admin for Google Sign-In, Cloudinary for media uploads&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure:&lt;/strong&gt; Docker Compose for local dev, Vercel for frontend, Render/Railway for backend, npm Workspaces as a monorepo&lt;/p&gt;

&lt;p&gt;One architectural detail we're proud of: &lt;strong&gt;end-to-end encrypted chat using ECDH P-256 key exchange&lt;/strong&gt;. Your conversations are genuinely yours — including stickers, GIFs, and file attachments up to 10MB.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Hard Parts (Honest Take)
&lt;/h2&gt;

&lt;p&gt;Real-time sync is deceptively brutal.&lt;/p&gt;

&lt;p&gt;Here's what actually went wrong:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Video sync drift&lt;/strong&gt; — even 200ms of lag breaks the illusion of watching together. We had to build a heartbeat-based elastic sync system to keep both users on the same frame continuously.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State inconsistencies on reconnect&lt;/strong&gt; — when a user drops and rejoins, the world needs to feel seamless. Getting that right took far more edge-case handling than we expected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proximity-based video activation&lt;/strong&gt; — making the PiP video call trigger naturally based on avatar closeness sounds simple. It introduced a whole class of race conditions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WebRTC in the wild&lt;/strong&gt; — peer-to-peer connections behave very differently across network types. NAT traversal, STUN/TURN fallbacks, and mobile networks all needed specific handling.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The hardest bugs weren't technical. They were &lt;em&gt;experiential&lt;/em&gt;. When does lag stop feeling like lag and start feeling like distance? That question shaped most of our debugging sessions.&lt;/p&gt;




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

&lt;p&gt;&lt;strong&gt;1. "Simple" is the most expensive feature.&lt;/strong&gt;&lt;br&gt;
We cut a lot. Every removal felt like a loss. But every cut made the core experience sharper and more emotionally coherent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Emotional UX is an underexplored field.&lt;/strong&gt;&lt;br&gt;
Most UI/UX writing focuses on task completion rates and conversion funnels. We were building for &lt;em&gt;feeling&lt;/em&gt;. There's very little playbook for that. We had to figure a lot of it out from first principles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Phaser 3 + React is a genuinely powerful combination — with real gotchas.&lt;/strong&gt;&lt;br&gt;
Keeping the game engine and the React UI in sync without stepping on each other required careful boundary design. Zustand as the shared state layer helped enormously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Real-time is never truly real-time.&lt;/strong&gt;&lt;br&gt;
There's always latency. The question is whether your sync system hides it well enough to preserve the illusion. We spent a surprising amount of time on perception, not performance.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why We Built This
&lt;/h2&gt;

&lt;p&gt;We're at a strange moment. We've never been more digitally connected. Loneliness has never been more of an epidemic.&lt;/p&gt;

&lt;p&gt;Every existing platform treats togetherness as a side effect of something else — productivity, gaming, entertainment. We wanted a space that existed &lt;em&gt;just&lt;/em&gt; to make two people feel less apart.&lt;/p&gt;

&lt;p&gt;TogetherUs won't fix long-distance. We know.&lt;/p&gt;

&lt;p&gt;But maybe it makes one couple's Sunday feel a little less lonely. Maybe it gives someone the feeling of sharing a couch they're 5,000 miles away from.&lt;/p&gt;

&lt;p&gt;That was worth building.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It / Star the Repo
&lt;/h2&gt;

&lt;p&gt;👉 &lt;strong&gt;Live:&lt;/strong&gt; &lt;a href="https://www.togetherus.in" rel="noopener noreferrer"&gt;https://www.togetherus.in&lt;/a&gt;&lt;br&gt;
👉 &lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/Deepak0yadav/TogetherUs" rel="noopener noreferrer"&gt;https://github.com/Deepak0yadav/TogetherUs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's open source under GPL-3.0. Contributions welcome — whether that's code, pixel art, bug reports, or just feedback on what togetherness should feel like.&lt;/p&gt;

&lt;p&gt;Drop a comment if you've built anything in the real-time or presence space — we'd love to compare notes.&lt;/p&gt;

&lt;p&gt;💼 &lt;strong&gt;Also shared this on LinkedIn&lt;/strong&gt; — &lt;a href="https://www.linkedin.com/posts/activity-7445155187947909120-qj1m?utm_source=social_share_send&amp;amp;utm_medium=member_desktop_web&amp;amp;rcm=ACoAAEPH3M0BI9gNk6qAAGYk-5BSbJWnTQlvp78" rel="noopener noreferrer"&gt;check out the post here&lt;/a&gt; if you'd like to connect or follow along.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Team
&lt;/h2&gt;

&lt;p&gt;Six of us built this. The irony of building a togetherness app as a distributed team was not lost on us.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/mayur-pawar-551a05278" rel="noopener noreferrer"&gt;Mayur Pawar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/deepak-yadav-25686217a" rel="noopener noreferrer"&gt;Deepak Yadav&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/shanidhya-kumar" rel="noopener noreferrer"&gt;Shanidhya Kumar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/kumar-yash-raj-749a4528b" rel="noopener noreferrer"&gt;Kumar Yash Raj&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/shobhit-aryan-6b2219334" rel="noopener noreferrer"&gt;Shobhit Aryan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.linkedin.com/in/abhishek-chahar-366ab2287" rel="noopener noreferrer"&gt;Abhishek Chahar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Distance means so little when someone means so much.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;code&gt;#buildinpublic&lt;/code&gt; &lt;code&gt;#showdev&lt;/code&gt; &lt;code&gt;#webdev&lt;/code&gt; &lt;code&gt;#opensource&lt;/code&gt; &lt;code&gt;#javascript&lt;/code&gt; &lt;code&gt;#react&lt;/code&gt; &lt;code&gt;#realtimeapps&lt;/code&gt; &lt;code&gt;#webrtc&lt;/code&gt; &lt;code&gt;#ux&lt;/code&gt; &lt;code&gt;#indiedev&lt;/code&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>showdev</category>
      <category>react</category>
      <category>opensource</category>
    </item>
    <item>
      <title>📱 Access Your Localhost Website on Mobile Without Hosting! 🚀</title>
      <dc:creator>Mayur Pawar</dc:creator>
      <pubDate>Sun, 02 Mar 2025 19:15:54 +0000</pubDate>
      <link>https://dev.to/mayur_pawar_9b0a092ca0f41/seamlessly-access-your-vs-code-webpage-on-mobile-via-localhost-gb6</link>
      <guid>https://dev.to/mayur_pawar_9b0a092ca0f41/seamlessly-access-your-vs-code-webpage-on-mobile-via-localhost-gb6</guid>
      <description>&lt;p&gt;Have you ever imagined how can you access the webpage on your mobile which is present on localhost. So today we are going to discuss on how can we view the same webpage on your phone without actually hosting it.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠 Step 1: Open Visual Studio Code
&lt;/h2&gt;

&lt;p&gt;Launch VS Code and make sure your project is ready to run.&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%2Fske1jxgtjlmaeuayfu1p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fske1jxgtjlmaeuayfu1p.png" alt=" " width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Step 2: Start Your Local Server
&lt;/h2&gt;

&lt;p&gt;Run your web project on localhost (e.g., npm start, live-server, etc.).&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%2F5k70pehzb5fe8qsq5cbv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5k70pehzb5fe8qsq5cbv.png" width="799" height="422"&gt;&lt;/a&gt;&lt;br&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%2Ffeyrv1kgujmf2h51g6ne.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffeyrv1kgujmf2h51g6ne.png" width="799" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  💻 Step 3: Open the Terminal in VS Code
&lt;/h2&gt;

&lt;p&gt;Navigate to Terminal in the top menu or use Ctrl + ` (backtick) to open it.&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%2F3xm8n5ytz52kf97vfpgz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3xm8n5ytz52kf97vfpgz.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🌐 Step 4: Enable Port Forwarding
&lt;/h2&gt;

&lt;p&gt;Click on the Port section in VS Code and select Forward Port.&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%2F6zqzjb2v7yzibntwty5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6zqzjb2v7yzibntwty5v.png" alt=" " width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔢 Step 5: Enter Your Port Number
&lt;/h2&gt;

&lt;p&gt;Type in the port number your project is running on (e.g., 3000, 5500, etc.) and press Enter.&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%2Fh82lj19rf21tj8m4vscu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh82lj19rf21tj8m4vscu.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔗 Step 6: Get Your Temporary Link
&lt;/h2&gt;

&lt;p&gt;Once the port is forwarded, a temporary link will be generated. Copy this link! 📋&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%2F9106hjod1qx8hmliq7e2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9106hjod1qx8hmliq7e2.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;br&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%2Fbkbqvuf64q1q04s5qhx6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbkbqvuf64q1q04s5qhx6.jpg" alt=" " width="720" height="1600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  📲 Step 7: Access It on Your Phone!
&lt;/h2&gt;

&lt;p&gt;📌 Open the link in your mobile browser, and voilà! 🎉 The same webpage running on your PC will now be visible on your phone.&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%2F0js3jy2ktnxc4ubhduix.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0js3jy2ktnxc4ubhduix.jpg" alt=" " width="720" height="1600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ Important Note:
&lt;/h2&gt;

&lt;p&gt;This link will only work as long as your project is running on localhost on your PC. So, make sure VS Code stays open and the project is active. ✅&lt;/p&gt;

&lt;p&gt;That’s it! You’re now browsing your localhost project on mobile like a pro. 😎 Let me know in the comments if this worked for you! 🚀✨&lt;/p&gt;

&lt;p&gt;🔥 Did you find this helpful? Don’t forget to ❤️ &amp;amp; 📝 leave a comment! 🚀&lt;/p&gt;

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