<?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: ujjwal</title>
    <description>The latest articles on DEV Community by ujjwal (@ujjwal_nepal).</description>
    <link>https://dev.to/ujjwal_nepal</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1389174%2F38334d37-50d6-4ba4-b5dd-07f21a887bb8.jpg</url>
      <title>DEV Community: ujjwal</title>
      <link>https://dev.to/ujjwal_nepal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ujjwal_nepal"/>
    <language>en</language>
    <item>
      <title>🐳 How Docker Saved My Full-Stack Project (And My Sanity)</title>
      <dc:creator>ujjwal</dc:creator>
      <pubDate>Mon, 01 Dec 2025 05:00:57 +0000</pubDate>
      <link>https://dev.to/ujjwal_nepal/how-docker-saved-my-full-stack-project-and-my-sanity-4o57</link>
      <guid>https://dev.to/ujjwal_nepal/how-docker-saved-my-full-stack-project-and-my-sanity-4o57</guid>
      <description>&lt;p&gt;When I built &lt;strong&gt;VBlog&lt;/strong&gt;, a full-stack application with Next.js, Express, Prisma, and PostgreSQL, everything ran flawlessly on my local machine.&lt;/p&gt;

&lt;p&gt;Then I tried deploying it to another environment.&lt;/p&gt;

&lt;p&gt;💥 Chaos ensued. Missing dependencies. Mismatched Node versions. Prisma binaries that refused to cooperate. PostgreSQL connection failures. The backend would work while the frontend crashed, or vice versa.&lt;/p&gt;

&lt;p&gt;That's when Docker shifted from a "someday" learning goal to an immediate necessity.&lt;/p&gt;

&lt;p&gt;In this article, I'll walk you through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why Docker became essential for my project&lt;/li&gt;
&lt;li&gt;How I containerized each component of my stack&lt;/li&gt;
&lt;li&gt;The Prisma binary issue that almost broke me (and how I fixed it)&lt;/li&gt;
&lt;li&gt;My final docker-compose workflow that ties everything together&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🤯 The "Works on My Machine" Nightmare
&lt;/h2&gt;

&lt;p&gt;My tech stack consisted of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js 15&lt;/strong&gt; for the frontend&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node.js + Express&lt;/strong&gt; for the backend API&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prisma ORM&lt;/strong&gt; for database operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL&lt;/strong&gt; as the database&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JWT&lt;/strong&gt; for authentication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything worked perfectly on my Fedora laptop. But when I tried containerizing the app using Alpine Linux, Prisma immediately complained:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error relocating query-engine-linux-musl: RELRO protection failed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The frontend built successfully locally but failed inside containers. PostgreSQL would start, but the backend couldn't establish reliable connections during startup.&lt;/p&gt;

&lt;p&gt;I was juggling three different environments—my host machine, the backend container, and the frontend container—each with its own quirks and failures.&lt;/p&gt;

&lt;p&gt;This is exactly where Docker proves its worth.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Why Docker Actually Matters
&lt;/h2&gt;

&lt;p&gt;Here's what Docker solved for me:&lt;/p&gt;

&lt;h3&gt;
  
  
  Consistent environments across machines
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Identical Node versions&lt;/li&gt;
&lt;li&gt;Same OS layer&lt;/li&gt;
&lt;li&gt;Matching Prisma engine binaries&lt;/li&gt;
&lt;li&gt;Predictable network configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once your app runs in Docker, it runs the same way everywhere Docker is installed—whether that's Linux, macOS, Windows, or cloud infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Zero manual dependency installation
&lt;/h3&gt;

&lt;p&gt;No one needs to install Node, PostgreSQL, Prisma, or package managers. Everything runs inside isolated containers.&lt;/p&gt;

&lt;h3&gt;
  
  
  True component isolation
&lt;/h3&gt;

&lt;p&gt;Each container has a single responsibility. The frontend container runs Next.js. The backend handles Node and Prisma. The database runs PostgreSQL. No version conflicts. No dependency interference.&lt;/p&gt;

&lt;h3&gt;
  
  
  Infrastructure as code
&lt;/h3&gt;

&lt;p&gt;One file (&lt;code&gt;docker-compose.yml&lt;/code&gt;) defines your entire stack.&lt;/p&gt;

&lt;p&gt;Start everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;--build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stop everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach eliminates roughly 80% of environment setup problems.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ Backend Dockerfile: Why I Switched from Alpine to Debian
&lt;/h2&gt;

&lt;p&gt;Initially, I chose Alpine Linux for its small image size. But Prisma and Alpine's musl libc implementation don't play nicely together, resulting in constant crashes.&lt;/p&gt;

&lt;p&gt;The solution: switch to &lt;strong&gt;debian-bullseye&lt;/strong&gt;, which uses glibc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:20-bullseye&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; openssl
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8000&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["npm", "start"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this change:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No more binary incompatibility errors&lt;/li&gt;
&lt;li&gt;Prisma worked reliably on every request&lt;/li&gt;
&lt;li&gt;The RELRO errors disappeared completely&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚛️ Frontend Dockerfile: Production-Ready Next.js
&lt;/h2&gt;

&lt;p&gt;I used a multi-stage build to keep the final image lean:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:20-bullseye&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;builder&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:20-bullseye&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;runner&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=builder /app ./&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["npm", "start"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces a production-optimized Next.js build ready for deployment.&lt;/p&gt;




&lt;h2&gt;
  
  
  🎼 The Complete Docker Compose Setup
&lt;/h2&gt;

&lt;p&gt;Here's how I orchestrated all three services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.9"&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:16&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vblog-postgres&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vblog&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres_data:/var/lib/postgresql/data&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5433:5432"&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD-SHELL"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pg_isready&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;-U&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;$$POSTGRES_USER"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;
      &lt;span class="na"&gt;start_period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;

  &lt;span class="na"&gt;backend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./backend&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vblog-backend&lt;/span&gt;
    &lt;span class="na"&gt;security_opt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;seccomp:unconfined&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;condition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;service_healthy&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;NODE_ENV&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;production&lt;/span&gt;
      &lt;span class="na"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres://postgres:password@postgres:5432/vblog?schema=public&lt;/span&gt;
      &lt;span class="na"&gt;PORT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8000&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8000:8000"&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="s"&gt;sh -c "npx prisma generate &amp;amp;&amp;amp;&lt;/span&gt;
             &lt;span class="s"&gt;npx prisma migrate deploy &amp;amp;&amp;amp;&lt;/span&gt;
             &lt;span class="s"&gt;npm start"&lt;/span&gt;

  &lt;span class="na"&gt;frontend&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./frontend&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vblog-frontend&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;backend&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;NEXT_PUBLIC_API_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://vblog-backend:8000&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;postgres_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this setup, I can launch the entire application stack with a single command, and it behaves identically on any machine.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔍 Debugging Tips That Saved Hours
&lt;/h2&gt;

&lt;h3&gt;
  
  
  View container logs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs &amp;lt;container-name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Inspect running containers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; vblog-backend sh
&lt;span class="nb"&gt;ls&lt;/span&gt; /app/node_modules/.prisma/client
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure Prisma for the correct platform
&lt;/h3&gt;

&lt;p&gt;Add this to your Prisma schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;binaryTargets = ["native", "debian-openssl-3.0.x"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Avoid Alpine unless necessary
&lt;/h3&gt;

&lt;p&gt;The combination of musl libc and Prisma often leads to compatibility headaches.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ What I Gained from Dockerizing
&lt;/h2&gt;

&lt;p&gt;The transformation was remarkable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Anyone can clone the repository and start the app with one command&lt;/li&gt;
&lt;li&gt;No more "Prisma engine not found" errors&lt;/li&gt;
&lt;li&gt;PostgreSQL connection issues vanished&lt;/li&gt;
&lt;li&gt;Development and production environments are identical&lt;/li&gt;
&lt;li&gt;The entire setup is deployment-ready&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker didn't just fix my environment issues—it made my project portable, predictable, and production-grade.&lt;/p&gt;




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

&lt;p&gt;If you're building a full-stack application with Node.js, Next.js, Prisma, and PostgreSQL, Docker should be part of your stack from the beginning.&lt;/p&gt;

&lt;p&gt;The debugging time it saves is substantial. The portability is unmatched. And deployment becomes dramatically simpler.&lt;/p&gt;

&lt;p&gt;Have you faced similar environment issues in your projects? How did you solve them? I'd love to hear your experiences in the comments below.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want to see the complete VBlog source code? Check out my &lt;a href="https://github.com/ujjwal-207/VBlogApp" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>prisma</category>
      <category>postgres</category>
      <category>express</category>
    </item>
    <item>
      <title>“The Struggle is Real. So is the Dream.”💭💻🌟</title>
      <dc:creator>ujjwal</dc:creator>
      <pubDate>Fri, 23 May 2025 16:22:45 +0000</pubDate>
      <link>https://dev.to/ujjwal_nepal/the-struggle-is-real-so-is-the-dream-lmd</link>
      <guid>https://dev.to/ujjwal_nepal/the-struggle-is-real-so-is-the-dream-lmd</guid>
      <description>&lt;h2&gt;
  
  
  💬 A Thought That Hit Me at Midnight
&lt;/h2&gt;

&lt;p&gt;So… today it happened again.&lt;/p&gt;

&lt;p&gt;That same overwhelming-but-somehow-motivating thought that hits when you're deep into a scroll spiral you didn’t plan.&lt;/p&gt;

&lt;p&gt;I was on &lt;strong&gt;LinkedIn&lt;/strong&gt;, just looking. But suddenly, it turned into a stress bomb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Layoffs.&lt;/li&gt;
&lt;li&gt;Hiring freezes.&lt;/li&gt;
&lt;li&gt;And every third post? “Just landed a 20 LPA package!” 😵‍💫&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And there I was—&lt;strong&gt;coffee in hand&lt;/strong&gt;, halfway through some &lt;strong&gt;DSA in Java&lt;/strong&gt;, balancing a &lt;strong&gt;React internship&lt;/strong&gt;, and just sitting there thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Why am I even doing this? Is there even a point anymore?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It felt like the whole software world was overbooked. &lt;strong&gt;Web dev? Saturated.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Jobs? Slowing down.&lt;/strong&gt;&lt;br&gt;
And me? Just trying to hold it all together.&lt;/p&gt;

&lt;p&gt;So I did what most of us do.&lt;/p&gt;

&lt;p&gt;I closed LinkedIn.&lt;br&gt;
Opened &lt;strong&gt;Instagram&lt;/strong&gt;.&lt;br&gt;
And started scrolling reels. 🌀&lt;/p&gt;




&lt;h2&gt;
  
  
  🎭 Reels, Escapes &amp;amp; Unexpected Realizations
&lt;/h2&gt;

&lt;p&gt;Insta was the usual escape:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Beautiful creators.&lt;/li&gt;
&lt;li&gt;Dancers.&lt;/li&gt;
&lt;li&gt;Actors lip-syncing.&lt;/li&gt;
&lt;li&gt;People going viral in a flash.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At first, it was just noise. But then… I caught myself thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Wait. Isn’t this space &lt;em&gt;saturated&lt;/em&gt; too?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are &lt;em&gt;so many&lt;/em&gt; influencers now. Every day, every scroll, someone new. It made me wonder:&lt;/p&gt;

&lt;p&gt;Why are &lt;em&gt;they&lt;/em&gt; still doing it?&lt;/p&gt;

&lt;p&gt;Then it hit me. The truth is—they're not just making reels.&lt;br&gt;
They're chasing something deeper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;They want to be seen. Admired. Respected. Remembered.&lt;/strong&gt;&lt;br&gt;
They want to be &lt;strong&gt;superstars&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;And aren’t &lt;em&gt;we&lt;/em&gt; the same?&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;We&lt;/strong&gt;, the devs. 💻👨‍💻👩‍💻&lt;br&gt;
We chase our own version of that spotlight: the &lt;strong&gt;dream job&lt;/strong&gt; ✨, the &lt;strong&gt;offer letter&lt;/strong&gt; 📩, the &lt;strong&gt;startup that takes off&lt;/strong&gt; 🚀, the &lt;strong&gt;20 LPA&lt;/strong&gt;, the &lt;strong&gt;unicorn badge on LinkedIn&lt;/strong&gt; 🦄💼.&lt;/p&gt;

&lt;p&gt;But let’s be real—&lt;br&gt;
We’re &lt;strong&gt;not Shah Rukh Khan&lt;/strong&gt; to keep doing the same &lt;em&gt;pose&lt;/em&gt; and still rule. 🫴✨&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;But even &lt;em&gt;he&lt;/em&gt; evolved.&lt;/strong&gt; 🔁👑&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the '90s, he gave us the classic SRK—the king of romance 💘, the open arms 🙌, the soft smile 😊. That &lt;strong&gt;signature pose&lt;/strong&gt;? Iconic. 🎬🌹&lt;/p&gt;

&lt;p&gt;But fast forward to now?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;He’s flipping cars 🚗💥, throwing punches 👊🔥, headlining action thrillers at &lt;strong&gt;57&lt;/strong&gt;. 🧨🎥&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;He evolved.&lt;/strong&gt; He didn’t survive by clinging to the past. He &lt;em&gt;adapted&lt;/em&gt;, even after owning an entire genre. 🔄🏆&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So why are &lt;em&gt;we&lt;/em&gt;, as devs, clinging to &lt;strong&gt;2016 tutorials&lt;/strong&gt; and expecting &lt;strong&gt;2025 jobs&lt;/strong&gt;? 📚🕰️💭&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s the part we skip in our hustle talks.&lt;/p&gt;

&lt;p&gt;The market isn’t just &lt;strong&gt;saturated&lt;/strong&gt;—it’s &lt;strong&gt;evolving&lt;/strong&gt;. 📈🌐&lt;br&gt;
The rules are changing. The easy wins? &lt;strong&gt;Gone.&lt;/strong&gt; ❌&lt;br&gt;
But the &lt;strong&gt;dream&lt;/strong&gt;? Oh, it’s still alive. 💡🔥&lt;/p&gt;




&lt;h2&gt;
  
  
  💪 Struggle Isn’t Failure — It’s the Entry Fee
&lt;/h2&gt;

&lt;p&gt;Here’s what I’m slowly learning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can’t avoid the grind.&lt;/li&gt;
&lt;li&gt;You can’t shortcut your way through evolution.&lt;/li&gt;
&lt;li&gt;You can’t keep doing the same “pose” and expect new results.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Even stars have to switch genres to stay in the game.&lt;/strong&gt; So do we.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Grind your DSA—but also learn &lt;em&gt;why&lt;/em&gt;, not just &lt;em&gt;how&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Get good at React—but explore the stack behind it.&lt;/li&gt;
&lt;li&gt;LeetCode? Yeah, it’s tough. But so is the gym—and that’s how you grow. 🧠💪&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Saturation doesn’t kill your dream. Stagnation does.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🌊 How I’m Trying to Stay Afloat
&lt;/h2&gt;

&lt;p&gt;No, I don’t have it all figured out. This post isn’t advice. It’s just me… processing out loud.&lt;/p&gt;

&lt;p&gt;But maybe you’re here too, feeling stuck in this flood of talent, trends, and job rejections.&lt;/p&gt;

&lt;p&gt;Here’s what I’m holding onto:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Be a T-shaped dev&lt;/strong&gt;: Deep in one thing, but aware of many.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build in public&lt;/strong&gt;: Even small projects can echo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ride waves with strategy&lt;/strong&gt;: AI, DevOps, Web3—explore, but don’t chase blindly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Find your tribe&lt;/strong&gt;: Get around people who push you.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;It’s not about who knows the most. It’s about who adapts the fastest.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🎯 My Final Rant (From One Dreamer to Another)
&lt;/h2&gt;

&lt;p&gt;Yes, this market is intense.&lt;br&gt;
Yes, you’ll doubt yourself—&lt;em&gt;a lot.&lt;/em&gt;&lt;br&gt;
Yes, there will be days you’ll feel behind. Maybe today’s one of them.&lt;/p&gt;

&lt;p&gt;But I promise:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Every “overnight success” was a long fight behind the scenes.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Every “dream job” post hides a hundred silent breakdowns.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Every “effortless dev” once cried over a LeetCode hard.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So if you're struggling, feeling small, tired, lost—same.&lt;/p&gt;

&lt;p&gt;But I also believe this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“The struggle is real. But so is the dream. And if you keep evolving, you’ll get there.” 🚀&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  📣 One Last Thought to Stick With You:
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Saturation doesn’t bury talent. It buries the ones who stop evolving.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;👇 If this felt like your story too—drop a ♻️, leave a comment, or just type “HUSTLE.”&lt;/p&gt;

&lt;p&gt;We’re in this together. 💻❤️‍🔥&lt;/p&gt;




</description>
    </item>
    <item>
      <title>🧠 Knowing When to Copy-Paste Is Also an Art 🎨</title>
      <dc:creator>ujjwal</dc:creator>
      <pubDate>Tue, 20 May 2025 06:21:29 +0000</pubDate>
      <link>https://dev.to/ujjwal_nepal/knowing-when-to-copy-paste-is-also-an-art-4nd9</link>
      <guid>https://dev.to/ujjwal_nepal/knowing-when-to-copy-paste-is-also-an-art-4nd9</guid>
      <description>&lt;p&gt;As junior developers, we’re constantly bombarded with advice from all directions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❌ "Don’t repeat yourself!"&lt;br&gt;
❌ "Avoid copy-paste coding!"&lt;br&gt;
❌ "Use loops, maps, functions – be clever!"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And I took that &lt;strong&gt;very&lt;/strong&gt; seriously. Like, maybe a bit &lt;em&gt;too&lt;/em&gt; seriously. 😅&lt;/p&gt;

&lt;h2&gt;
  
  
  The Hustle to Be a "Cool" Dev 🧑‍💻
&lt;/h2&gt;

&lt;p&gt;In my projects, I went above and beyond to avoid repetition. Even if a simple copy-paste would’ve worked just fine, I would twist my logic into a pretzel 🥨 using &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;, and whatever else I could find on YouTube tutorials just to prove:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I’m not a repetitive coder. I’m &lt;em&gt;different&lt;/em&gt;. I’m cool 😎."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But let’s be real – deep down, I just wanted my seniors at work to think I’m smart.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Wake-Up Call 🔔
&lt;/h2&gt;

&lt;p&gt;One day, while my senior was reviewing my code, he paused and looked confused.&lt;/p&gt;

&lt;p&gt;👨‍💼: "Why are you doing this hard stuff?"&lt;br&gt;
👦 (me): "What hard stuff?"&lt;br&gt;
👨‍💼: "These weird loops and logic... it’s too complicated."&lt;br&gt;
👦: "But… we’re not supposed to repeat code, right?"&lt;br&gt;
👨‍💼: "Says who?"&lt;br&gt;
👦: "Uhh… everyone?"&lt;/p&gt;

&lt;p&gt;Then he dropped a truth bomb 💣 on me that I’ll never forget:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"&lt;strong&gt;You're writing &lt;em&gt;your&lt;/em&gt; program. Do what makes things easy for &lt;em&gt;you&lt;/em&gt;.&lt;/strong&gt;&lt;br&gt;
We program to &lt;strong&gt;make things simple&lt;/strong&gt;, not complicated.&lt;br&gt;
The &lt;em&gt;client&lt;/em&gt; wants a working product – they don’t care if you used &lt;code&gt;forEach&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt;, or handwritten each line.&lt;br&gt;
&lt;strong&gt;Make the product cool, not your code.&lt;/strong&gt;&lt;br&gt;
So do the easy thing. Make it work."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  That Hit Hard. 🫠
&lt;/h2&gt;

&lt;p&gt;He was right.&lt;/p&gt;

&lt;p&gt;I realized I was coding for validation, not for clarity. I was trying to impress, not solve. And worst of all, I was over-engineering something simple because I feared being called "repetitive."&lt;/p&gt;

&lt;p&gt;But here’s the truth 👇&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ Sometimes Being Repetitive Is Okay
&lt;/h2&gt;

&lt;p&gt;You’re still learning.&lt;br&gt;
You’re building something that works.&lt;br&gt;
You’re meeting the requirements.&lt;br&gt;
That’s &lt;em&gt;enough.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Not everything needs to be "optimized" or "abstracted" from day one. Over time, you’ll naturally refactor things as the project grows. But early on?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🔁 A little copy-paste never hurt anybody. 😉&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;ul&gt;
&lt;li&gt;Learn every day. Stay hungry. 🍽️&lt;/li&gt;
&lt;li&gt;Don’t be afraid to repeat yourself when it makes sense.&lt;/li&gt;
&lt;li&gt;Write code that works and makes your life easier.&lt;/li&gt;
&lt;li&gt;Impress your &lt;em&gt;future self&lt;/em&gt; with clean, understandable logic – not your current team with unnecessary cleverness.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;🙌 Thanks for reading. If you’ve ever fallen into the trap of “over-engineering to impress,” drop a 🧠 in the comments and let’s talk!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🤖📚 Build Your Own AI-Powered Book Chatbot using Python, Flask, Lang Chain, and Pinecone!</title>
      <dc:creator>ujjwal</dc:creator>
      <pubDate>Mon, 05 May 2025 13:58:29 +0000</pubDate>
      <link>https://dev.to/ujjwal_nepal/build-your-own-ai-powered-book-chatbot-using-python-flask-lang-chain-and-pinecone-loi</link>
      <guid>https://dev.to/ujjwal_nepal/build-your-own-ai-powered-book-chatbot-using-python-flask-lang-chain-and-pinecone-loi</guid>
      <description>&lt;p&gt;Hey Devs! 👋&lt;br&gt;
Have you ever wanted to &lt;strong&gt;chat with your favorite books&lt;/strong&gt; like you're texting a friend? 📖💬&lt;br&gt;
Well, you're in the right place! In this blog post, I’ll walk you through how I built &lt;strong&gt;BookChatBot&lt;/strong&gt;, an AI-powered chatbot that can &lt;strong&gt;answer questions about a book&lt;/strong&gt;, using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧠 LangChain (for LLM logic)&lt;/li&gt;
&lt;li&gt;🌲 Pinecone (for vector search)&lt;/li&gt;
&lt;li&gt;🧾 PDF loading and splitting&lt;/li&gt;
&lt;li&gt;⚡ Google Gemini (for answering questions)&lt;/li&gt;
&lt;li&gt;🧪 Flask (as the web framework)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can find the full code on GitHub:&lt;br&gt;
👉 &lt;a href="https://github.com/ujjwal-207/bookchatbot-" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  💡 What are we building?
&lt;/h2&gt;

&lt;p&gt;We're building a &lt;strong&gt;chatbot web app&lt;/strong&gt; that can read PDFs (like a book 📘), store them in Pinecone’s vector database, and allow users to ask &lt;strong&gt;questions&lt;/strong&gt; about the content!&lt;br&gt;
The AI will retrieve the most relevant chunks and generate human-like answers using &lt;strong&gt;Google's Gemini model&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💸 Note: Pinecone’s free tier only allows one index. So for now, you can't dynamically upload new books — but once set up, it's super efficient for Q&amp;amp;A!&lt;/p&gt;
&lt;/blockquote&gt;


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


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;bookchatbot-/
├── app.py               &lt;span class="c"&gt;# Flask app and RAG chain&lt;/span&gt;
├── helper.py            &lt;span class="c"&gt;# PDF loading, chunking, and embeddings&lt;/span&gt;
├── src/
│   ├── prompt.py        &lt;span class="c"&gt;# System prompt for LLM&lt;/span&gt;
├── data/                &lt;span class="c"&gt;# Folder with your PDF files&lt;/span&gt;
├── templates/
│   └── chat.html        &lt;span class="c"&gt;# Simple frontend&lt;/span&gt;
├── .env                 &lt;span class="c"&gt;# API keys (not shared!)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🧠 How does it work?
&lt;/h2&gt;

&lt;p&gt;This is a &lt;strong&gt;RAG (Retrieval-Augmented Generation)&lt;/strong&gt; pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Load and split PDFs into chunks&lt;/li&gt;
&lt;li&gt;Convert chunks into vector embeddings&lt;/li&gt;
&lt;li&gt;Store in Pinecone (vector DB)&lt;/li&gt;
&lt;li&gt;Accept user question&lt;/li&gt;
&lt;li&gt;Find the top relevant chunks (via Pinecone)&lt;/li&gt;
&lt;li&gt;Use Gemini to answer based on retrieved content&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;
  
  
  🧾 helper.py – Preprocessing the PDFs
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_pdf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;loader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DirectoryLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;glob&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;*.pdf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;loader_cls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PyMuPDFLoader&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;loader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;📥 We load all PDFs from the &lt;code&gt;data/&lt;/code&gt; folder.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;text_splitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extraced_date&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;text_split&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RecursiveCharacterTextSplitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk_size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunk_overlap&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;text_split&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extraced_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📚 We split documents into manageable 500-token chunks to help with better retrieval.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_geneni_embeddings&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;GoogleGenerativeAIEmbeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;models/embedding-001&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;google_api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GOOGLE_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;embeddings&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔍 We use Google's &lt;strong&gt;embedding model&lt;/strong&gt; to turn text chunks into vectors!&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 app.py – The Flask App + AI Brain
&lt;/h2&gt;

&lt;p&gt;We start by setting up Pinecone:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Pinecone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PINECONE_API_KEY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;docsearch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PineconeVectorStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_existing_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;bookchat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;retriver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;docsearch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;as_retriever&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;search_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;similarity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;search_kwargs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;k&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧠 This allows us to &lt;strong&gt;retrieve 3 most similar chunks&lt;/strong&gt; from our stored book.&lt;/p&gt;

&lt;p&gt;Then we build a prompt + Gemini LLM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;llm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatGoogleGenerativeAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gemini-2.0-flash&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatPromptTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_messages&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;system&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;system_prompt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;human&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;{input}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💬 &lt;code&gt;system_prompt&lt;/code&gt; defines how the AI should behave (e.g., polite, detailed).&lt;/p&gt;

&lt;p&gt;Create the RAG chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;question_answer_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_stuff_documents_chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;rag_chain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create_retrieval_chain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;retriver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;question_answer_chain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;💡 This is the brain of the chatbot — retrieval + generation.&lt;/p&gt;

&lt;p&gt;Finally, the Flask endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;chat.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/get&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;chat&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;msg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rag_chain&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;answer&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📡 The front end sends a message → gets a smart reply from the AI!&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Testing it Out
&lt;/h2&gt;

&lt;p&gt;Just run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open &lt;code&gt;http://localhost:8080&lt;/code&gt; and start chatting with your book! 🗨️📕&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚠️ Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Pinecone’s free tier = &lt;strong&gt;only one index&lt;/strong&gt;. So, you can't upload new books at runtime unless you upgrade or manage your own embedding storage.&lt;/li&gt;
&lt;li&gt;Static loading: you must re-run the app if you want to embed a different book.&lt;/li&gt;
&lt;li&gt;Basic HTML frontend – could be upgraded with React, Tailwind, or Chat UI kits.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Ideas for Improvements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add &lt;strong&gt;file upload&lt;/strong&gt; (if using a paid Pinecone plan or local vector store like FAISS)&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;streaming responses&lt;/strong&gt; for a more chat-like feel&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;authentication&lt;/strong&gt; and user-specific history&lt;/li&gt;
&lt;li&gt;Display source chunk(s) below each answer for transparency&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;Building an AI chatbot like this is easier than ever thanks to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧠 LangChain for chaining LLM workflows&lt;/li&gt;
&lt;li&gt;🌲 Pinecone for fast vector search&lt;/li&gt;
&lt;li&gt;⚡ Google Gemini for intelligent responses&lt;/li&gt;
&lt;li&gt;🧪 Flask for quick APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you liked this post, don’t forget to ⭐ the &lt;a href="https://github.com/ujjwal-207/bookchatbot-" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt; and follow me here on Dev.to!&lt;/p&gt;

&lt;p&gt;Got questions or ideas? Drop them below! 💬👇&lt;/p&gt;




</description>
    </item>
    <item>
      <title>🔍 Font Finder: Never Wonder "What Font Is That?" Again</title>
      <dc:creator>ujjwal</dc:creator>
      <pubDate>Thu, 06 Mar 2025 07:17:18 +0000</pubDate>
      <link>https://dev.to/ujjwal_nepal/font-finder-never-wonder-what-font-is-that-again-312p</link>
      <guid>https://dev.to/ujjwal_nepal/font-finder-never-wonder-what-font-is-that-again-312p</guid>
      <description>&lt;h2&gt;
  
  
  🎨 The Problem: Identifying Fonts Is a Pain
&lt;/h2&gt;

&lt;p&gt;We've all been there. You come across a stunning website, a sleek UI, or a beautifully designed ad, and the font just &lt;em&gt;clicks&lt;/em&gt;.  &lt;/p&gt;

&lt;p&gt;&lt;em&gt;"That’s the one! I need this for my project!"&lt;/em&gt;  &lt;/p&gt;

&lt;p&gt;But then reality kicks in:&lt;br&gt;&lt;br&gt;
❌ You have no clue what the font is.&lt;br&gt;&lt;br&gt;
❌ It could be a premium or free typeface.&lt;br&gt;&lt;br&gt;
❌ Finding a close match is a tedious process.  &lt;/p&gt;

&lt;p&gt;Until now, your only options were:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Guessing &amp;amp; Googling&lt;/strong&gt; → Endless font library searches.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Crowdsourcing&lt;/strong&gt; → Posting on forums and hoping for help.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual Matching&lt;/strong&gt; → Painstakingly comparing fonts side by side.
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  🚀 Enter Font Finder
&lt;/h3&gt;

&lt;p&gt;Font Finder solves this by using &lt;strong&gt;AI-powered font detection&lt;/strong&gt;. Upload an image, and within seconds, get accurate font matches—no more guessing games.  &lt;/p&gt;

&lt;p&gt;Built with &lt;strong&gt;Next.js, React, and Tailwind CSS&lt;/strong&gt;, and powered by &lt;strong&gt;Google’s Gemini 1.5 Flash AI model&lt;/strong&gt;, this tool provides &lt;strong&gt;fast and precise font recognition&lt;/strong&gt; with minimal effort.  &lt;/p&gt;


&lt;h2&gt;
  
  
  🛠️ Under the Hood: How Font Finder Works
&lt;/h2&gt;

&lt;p&gt;At its core, Font Finder leverages &lt;strong&gt;multimodal AI&lt;/strong&gt; to analyze both &lt;strong&gt;visual&lt;/strong&gt; and &lt;strong&gt;textual&lt;/strong&gt; characteristics of fonts. Unlike traditional font-matching methods that rely on pre-defined databases, Font Finder &lt;em&gt;understands&lt;/em&gt; typography.  &lt;/p&gt;

&lt;p&gt;Here’s a simplified version of how image-based font detection works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Process the uploaded image and detect fonts using AI&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;detectFontFromImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;imageData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;genAI&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;initializeGeminiAI&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;genAI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getGenerativeModel&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gemini-1.5-flash&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;base64Data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;imageData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mimeType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;imageData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;imagePart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;inlineData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;base64Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;mimeType&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateContent&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;fontAnalysisPrompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;imagePart&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;processResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach offers significant advantages over traditional methods:&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;AI-powered recognition&lt;/strong&gt; → Goes beyond pattern matching.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Understands font context&lt;/strong&gt; → Recognizes variations in weight, style, and spacing.&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Works with real-world images&lt;/strong&gt; → Handles noise, distortions, and different lighting conditions.  &lt;/p&gt;


&lt;h2&gt;
  
  
  🔎 How to Use Font Finder
&lt;/h2&gt;

&lt;p&gt;There are &lt;strong&gt;two ways&lt;/strong&gt; to identify fonts:  &lt;/p&gt;
&lt;h3&gt;
  
  
  📸 Image-Based Font Detection
&lt;/h3&gt;

&lt;p&gt;Found a cool font in the wild?&lt;br&gt;&lt;br&gt;
1️⃣ Take a picture.&lt;br&gt;&lt;br&gt;
2️⃣ Upload it to Font Finder.&lt;br&gt;&lt;br&gt;
3️⃣ Get instant font matches.  &lt;/p&gt;
&lt;h3&gt;
  
  
  📝 Text-Based Font Detection
&lt;/h3&gt;

&lt;p&gt;Already have a sample text but don’t know the font?&lt;br&gt;&lt;br&gt;
1️⃣ Paste the text.&lt;br&gt;&lt;br&gt;
2️⃣ Click &lt;strong&gt;"Detect Font"&lt;/strong&gt;.&lt;br&gt;&lt;br&gt;
3️⃣ View the closest matches with confidence scores.  &lt;/p&gt;


&lt;h2&gt;
  
  
  🔤 What You Get: A Full Typography Profile
&lt;/h2&gt;

&lt;p&gt;Font Finder doesn’t just tell you the font name—it gives a &lt;strong&gt;detailed breakdown&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🏷 &lt;strong&gt;Font Family&lt;/strong&gt; → The exact match or closest alternatives.
&lt;/li&gt;
&lt;li&gt;🔠 &lt;strong&gt;Weight Classification&lt;/strong&gt; → Light, Regular, Medium, Bold, etc.
&lt;/li&gt;
&lt;li&gt;✍ &lt;strong&gt;Style Properties&lt;/strong&gt; → Italic, Condensed, Extended, etc.
&lt;/li&gt;
&lt;li&gt;🎯 &lt;strong&gt;Confidence Score&lt;/strong&gt; → AI certainty level.
&lt;/li&gt;
&lt;li&gt;🔗 &lt;strong&gt;Similar Fonts&lt;/strong&gt; → Alternative suggestions for flexibility.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For designers and developers, this means &lt;strong&gt;no more losing track of great fonts&lt;/strong&gt;.  &lt;/p&gt;


&lt;h2&gt;
  
  
  🏗️ For Developers: Easy Integration &amp;amp; Customization
&lt;/h2&gt;

&lt;p&gt;Want to integrate Font Finder’s detection into your own project? It’s super simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the repository&lt;/span&gt;
git clone https://github.com/ujjwal-207/Font-finder.git

&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt;

&lt;span class="c"&gt;# Set up environment variables&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"GEMINI_API_KEY=your_api_key_here"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; .env.local

&lt;span class="c"&gt;# Start the development server&lt;/span&gt;
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a &lt;strong&gt;modular architecture and clean codebase&lt;/strong&gt;, you can easily:&lt;br&gt;&lt;br&gt;
🔹 Customize the UI with Tailwind CSS.&lt;br&gt;&lt;br&gt;
🔹 Extend the functionality with additional AI models.&lt;br&gt;&lt;br&gt;
🔹 Integrate it into &lt;strong&gt;your&lt;/strong&gt; apps or workflows.  &lt;/p&gt;




&lt;h2&gt;
  
  
  🎨 Bonus: Color Detection
&lt;/h2&gt;

&lt;p&gt;Font Finder also provides &lt;strong&gt;basic color detection&lt;/strong&gt; from images, helping you identify the dominant colors used in typography.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limitations:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
⚠️ Lighting and screen calibration can affect accuracy.&lt;br&gt;&lt;br&gt;
⚠️ RGB vs. CMYK can cause slight variations.&lt;br&gt;&lt;br&gt;
⚠️ Print vs. digital colors may differ.  &lt;/p&gt;

&lt;p&gt;Still, it’s a handy &lt;strong&gt;extra tool&lt;/strong&gt; for getting in the right color neighborhood.  &lt;/p&gt;




&lt;h2&gt;
  
  
  🧠 The Technical Challenge (And How We Solved It)
&lt;/h2&gt;

&lt;p&gt;Font detection isn’t as straightforward as it seems. Here are some challenges we tackled:  &lt;/p&gt;

&lt;p&gt;🔍 &lt;strong&gt;Fonts Look Different in Different Contexts&lt;/strong&gt; → AI learns from multiple character variations.&lt;br&gt;&lt;br&gt;
🔍 &lt;strong&gt;Some Typefaces Are Nearly Identical&lt;/strong&gt; → Advanced AI models detect subtle differences.&lt;br&gt;&lt;br&gt;
🔍 &lt;strong&gt;Weight &amp;amp; Style Variations&lt;/strong&gt; → Gemini AI can distinguish Regular vs. Bold vs. Italic.&lt;br&gt;&lt;br&gt;
🔍 &lt;strong&gt;Low-Quality Images&lt;/strong&gt; → The model compensates for blur and distortions.  &lt;/p&gt;

&lt;p&gt;Thanks to &lt;strong&gt;multimodal AI&lt;/strong&gt;, Font Finder doesn’t just &lt;em&gt;compare&lt;/em&gt; fonts—it &lt;em&gt;understands&lt;/em&gt; typography.  &lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Try It Now!
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;strong&gt;&lt;a href="https://github.com/ujjwal-207/Font-finder" rel="noopener noreferrer"&gt;Check out Font Finder on GitHub&lt;/a&gt;&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;💡 It’s &lt;strong&gt;open-source&lt;/strong&gt;, so feel free to:&lt;br&gt;&lt;br&gt;
✅ Contribute improvements&lt;br&gt;&lt;br&gt;
✅ Suggest new features&lt;br&gt;&lt;br&gt;
✅ Fork and build your own version  &lt;/p&gt;




&lt;p&gt;💬 &lt;em&gt;What font have you been trying to identify? Drop a comment below if Font Finder helped you solve your typography mystery!&lt;/em&gt; 🚀&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>productivity</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>I am Lazy and Exam is here,So here is Easy way to kill It.</title>
      <dc:creator>ujjwal</dc:creator>
      <pubDate>Mon, 24 Feb 2025 13:16:02 +0000</pubDate>
      <link>https://dev.to/ujjwal_nepal/i-am-lazy-and-exam-is-hereso-here-is-easy-way-to-kill-it-4nod</link>
      <guid>https://dev.to/ujjwal_nepal/i-am-lazy-and-exam-is-hereso-here-is-easy-way-to-kill-it-4nod</guid>
      <description>&lt;p&gt;&lt;strong&gt;I Know Hard Work is the Only Way💪&lt;/strong&gt;&lt;br&gt;
There’s no shortcut to success🛣️—no magic powers🪄, no Doraemon gadgets🤖 to cheat in exams, and no secret brain exercises🧠 to instantly learn everything.&lt;/p&gt;

&lt;p&gt;But what I do best is finding smart ways to tackle tough situations. So, here’s my approach—let’s break down topics step by step and practice effectively!&lt;/p&gt;

&lt;h2&gt;
  
  
  I have build this habit👨‍💻
&lt;/h2&gt;

&lt;p&gt;I just can't simply understand things by just studying topic i have do some practise in that topic to understand it clearly.And here come the doremon gadget to make me practise properly to ace my exam ie &lt;strong&gt;&lt;em&gt;Practise Question&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Practise Question
&lt;/h2&gt;

&lt;p&gt;This is the &lt;strong&gt;superAi⚙️&lt;/strong&gt; Tool which will give all the sets of practise question with its solution, if you just enter the topic name or any subtopic which you want to understand clearly and ace the exam.You have the option to choose like if you are new to the topic,you are intermediate in the topic and you want to be pro.Or you want to try some new difficult question which will make your understanding more stronger.&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%2Fysa62jxh8vsy5rykv9ec.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%2Fysa62jxh8vsy5rykv9ec.png" alt="Image description" width="800" height="697"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  So Lets Use this Gadget🤖
&lt;/h2&gt;

&lt;p&gt;This is simple Nextjs program you can just run it in your local device.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here is the way to do it&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Clone this repo&lt;br&gt;
&lt;code&gt;https://github.com/ujjwal-207/practice-question.git&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create your .env file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter you Gemini api key&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And all set to ace your exam🎯&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>nextjs</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
