<?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: Karthikeyan</title>
    <description>The latest articles on DEV Community by Karthikeyan (@imkarthikeyan).</description>
    <link>https://dev.to/imkarthikeyan</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%2F236404%2Fcae6d62e-c9f5-4bfe-b4e1-b62af40a6837.jpg</url>
      <title>DEV Community: Karthikeyan</title>
      <link>https://dev.to/imkarthikeyan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/imkarthikeyan"/>
    <language>en</language>
    <item>
      <title>I Missed 3 Hackathons This Year. So I Built DevPulse to Fix That.</title>
      <dc:creator>Karthikeyan</dc:creator>
      <pubDate>Mon, 02 Mar 2026 08:00:41 +0000</pubDate>
      <link>https://dev.to/imkarthikeyan/i-missed-3-hackathons-this-year-so-i-built-devpulse-to-fix-that-260e</link>
      <guid>https://dev.to/imkarthikeyan/i-missed-3-hackathons-this-year-so-i-built-devpulse-to-fix-that-260e</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/weekend-2026-02-28"&gt;DEV Weekend Challenge: Community&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;It happened again last week.&lt;/p&gt;

&lt;p&gt;I was scrolling through Twitter and saw someone post their submission for a hackathon I'd never heard of. Great prizes. Interesting prompt. Deadline: yesterday.&lt;/p&gt;

&lt;p&gt;I'm a Senior Software Engineer. I follow hundreds of devs. I'm on Reddit, DEV.to, Discord servers, newsletters. And somehow, I still missed it.&lt;/p&gt;

&lt;p&gt;It's not just hackathons either. New frameworks drop and I'm the last to know. A tool that would've saved me 10 hours of work existed for 3 months before I stumbled across it. The dev world moves &lt;em&gt;fast&lt;/em&gt;, and keeping up feels like a full-time job on top of an already full-time job.&lt;/p&gt;

&lt;p&gt;I don't need more noise. I need a &lt;strong&gt;signal&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Built: DevPulse 🗞️
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;DevPulse&lt;/strong&gt; is a personalized AI briefing tool for developers. You tell it your stack and what you care about — and it surfaces exactly what's relevant to you, right now.&lt;/p&gt;

&lt;p&gt;No generic "top 10 tools of the week" listicles. No algorithm trying to sell you ads. Just a clean, focused briefing built around &lt;em&gt;your&lt;/em&gt; world as a developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  What it shows you:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔧 &lt;strong&gt;New Tools &amp;amp; Frameworks&lt;/strong&gt; — relevant to your stack&lt;/li&gt;
&lt;li&gt;🏆 &lt;strong&gt;Active &amp;amp; Upcoming Hackathons&lt;/strong&gt; — so you never miss one again&lt;/li&gt;
&lt;li&gt;📦 &lt;strong&gt;Notable OSS Releases&lt;/strong&gt; — the repos worth watching&lt;/li&gt;
&lt;li&gt;🔥 &lt;strong&gt;Community Buzz&lt;/strong&gt; — what devs are actually talking about&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How it works:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Tell DevPulse your stack (React, Python, Go, AI/ML — whatever you work with)&lt;/li&gt;
&lt;li&gt;Pick your interests (hackathons, OSS, career, new frameworks, etc.)&lt;/li&gt;
&lt;li&gt;Choose your style: &lt;strong&gt;Quick Scan&lt;/strong&gt; or &lt;strong&gt;Deep Dive&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Get your briefing — personalized, AI-generated, ready in seconds&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Under the hood, it uses Gemini with web search grounding to pull fresh, relevant information — not stale training data.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Community It's For
&lt;/h2&gt;

&lt;p&gt;This is built for the &lt;strong&gt;dev Twitter / online dev community&lt;/strong&gt; — the people who are constantly building, learning, and shipping. The ones who care about what's next, not just what's now.&lt;/p&gt;

&lt;p&gt;Whether you're a solo indie hacker, a team lead at a startup, or someone grinding through hackathons on weekends — DevPulse is for you if you've ever felt like the dev world is moving faster than you can track.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; React + Tailwind (clean, dark, Linear-inspired UI)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI:&lt;/strong&gt; Google Gemini 2.5 Flash with web search grounding&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limiting:&lt;/strong&gt; API key per user — your key, your quota, your privacy. No black-box backend holding your data.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;The hardest part wasn't the code. It was figuring out what &lt;em&gt;not&lt;/em&gt; to build.&lt;/p&gt;

&lt;p&gt;My first instinct was to build something that aggregated everything — every newsletter, every RSS feed, every subreddit. But that's just recreating the noise problem with extra steps.&lt;/p&gt;

&lt;p&gt;The insight that unlocked it: &lt;strong&gt;personalization is the feature&lt;/strong&gt;. A briefing about Rust releases is useless to me if I write Python. Hackathon alerts are noise if I'm not looking to compete. The value isn't in the information — it's in the &lt;em&gt;filtering&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Gemini's ability to reason about relevance and generate structured, scannable output made this possible to build in a weekend.&lt;/p&gt;




&lt;p&gt;Screenshot&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%2Fak0h9xc4l5qowghtknp1.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%2Fak0h9xc4l5qowghtknp1.png" alt="demo" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://dev-pulse-ten.vercel.app/" rel="noopener noreferrer"&gt;https://dev-pulse-ten.vercel.app/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/skarthikeyan96/dev-pulse" rel="noopener noreferrer"&gt;https://github.com/skarthikeyan96/dev-pulse&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Drop your stack into DevPulse and let me know what you think in the comments. And if you know of a hackathon I should add to my calendar — hit me up. 😄&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built for the "Build for Your Community" weekend challenge. The community: every developer who's ever felt like the world moved on without them.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>🏃 StrideBoard — A Community Hype Wall for Runners</title>
      <dc:creator>Karthikeyan</dc:creator>
      <pubDate>Sun, 01 Mar 2026 13:28:55 +0000</pubDate>
      <link>https://dev.to/imkarthikeyan/strideboard-a-community-hype-wall-for-runners-2k9b</link>
      <guid>https://dev.to/imkarthikeyan/strideboard-a-community-hype-wall-for-runners-2k9b</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/weekend-2026-02-28"&gt;DEV Weekend Challenge: Community&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Community
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Runners.&lt;/strong&gt; All of them — from the person chasing their first 5K finish to the ultramarathoner logging 100-mile weeks. Whether you're training for TCS World 10K Bengaluru, a local park run, or a marathon on the other side of the world, every runner carries a goal that deserves to be said out loud.&lt;/p&gt;

&lt;p&gt;I'm currently training for the &lt;strong&gt;TCS World 10K Bengaluru&lt;/strong&gt; and I wanted a place where runners could declare their goals publicly — and have the community send energy back. Race day is personal, but the journey to the start line is communal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;StrideBoard&lt;/strong&gt; is built for all of them.&lt;/p&gt;




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

&lt;p&gt;&lt;strong&gt;StrideBoard&lt;/strong&gt; — a community race goal hype wall for runners everywhere.&lt;/p&gt;

&lt;p&gt;Runners can drop their race goal on the board — their target time, goal type, target pace, and a short message about what's driving them. The community can then 🔥 hype each card. It's part bulletin board, part leaderboard, part pre-race ritual.&lt;/p&gt;

&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🎯 &lt;strong&gt;Goal Cards&lt;/strong&gt; — post your race goal with target time, pace, and a motivation message&lt;/li&gt;
&lt;li&gt;🔥 &lt;strong&gt;Hype Button&lt;/strong&gt; — one-tap community support, fully anonymous count&lt;/li&gt;
&lt;li&gt;🎭 &lt;strong&gt;Goal Types&lt;/strong&gt; — Personal Best, Sub-60, First Ever Race, Just Finish Strong, Injury Comeback&lt;/li&gt;
&lt;li&gt;🕶️ &lt;strong&gt;Privacy by default&lt;/strong&gt; — auto-generated runner nicknames (like &lt;code&gt;SwiftGazelle47&lt;/code&gt;) with a one-click anonymous mode so no real names are ever stored&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;Community Stats&lt;/strong&gt; — runners in, total hypes, sub-60 chasers, first-timers&lt;/li&gt;
&lt;li&gt;🏆 &lt;strong&gt;Top Hyped Leaderboard&lt;/strong&gt; — the most-supported runners float to the top&lt;/li&gt;
&lt;li&gt;⏱️ &lt;strong&gt;Live Race Countdown&lt;/strong&gt; — days to your target race + a 16-week training progress bar&lt;/li&gt;
&lt;li&gt;📡 &lt;strong&gt;Real-time Redis backend&lt;/strong&gt; — shared state across all users, no stale data&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;a href="https://strideboard-rose.vercel.app/" rel="noopener noreferrer"&gt;https://strideboard-rose.vercel.app/&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/skarthikeyan96" rel="noopener noreferrer"&gt;
        skarthikeyan96
      &lt;/a&gt; / &lt;a href="https://github.com/skarthikeyan96/strideboard" rel="noopener noreferrer"&gt;
        strideboard
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;StrideBoard 🏃&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A community hype wall where runners everywhere can post their race goals and get hyped up by the crowd. 🔥&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Deploy to Vercel&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;1. Get Upstash credentials&lt;/h3&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://console.upstash.com" rel="nofollow noopener noreferrer"&gt;console.upstash.com&lt;/a&gt; and create a free Redis database&lt;/li&gt;
&lt;li&gt;Choose the &lt;strong&gt;Mumbai (ap-south-1)&lt;/strong&gt; region for lowest latency&lt;/li&gt;
&lt;li&gt;Copy the &lt;strong&gt;REST URL&lt;/strong&gt; and &lt;strong&gt;REST Token&lt;/strong&gt; from the database page&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;2. Deploy&lt;/h3&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm i -g vercel    &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; if you don't have it&lt;/span&gt;
vercel             &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; follow prompts — deploy as-is, no framework&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;3. Get OpenAI API key (content moderation)&lt;/h3&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://platform.openai.com" rel="nofollow noopener noreferrer"&gt;platform.openai.com&lt;/a&gt; and sign in&lt;/li&gt;
&lt;li&gt;API keys → Create new secret key&lt;/li&gt;
&lt;li&gt;The app uses the &lt;strong&gt;Moderation API&lt;/strong&gt; only (no ChatGPT usage)&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;4. Add environment variables&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;In the Vercel dashboard → your project → Settings → Environment Variables, add:&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UPSTASH_REST_URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://xxxx.upstash.io&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UPSTASH_REST_TOKEN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AXxxxx...&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OPENAI_API_KEY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Your OpenAI API key (for moderation)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ALLOWED_ORIGIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://your-app.vercel.app&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Optional (defaults to your Vercel URL)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/skarthikeyan96/strideboard" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;







&lt;h2&gt;
  
  
  Screenshot
&lt;/h2&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%2Flo10svnbt9eu9ilem728.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%2Flo10svnbt9eu9ilem728.png" alt="screen"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;This was a deliberately lean stack — the goal was to ship fast and keep it deployable in one command.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Choice&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Vanilla HTML/CSS/JS&lt;/td&gt;
&lt;td&gt;Zero build step, fast to iterate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Vercel Serverless Function&lt;/td&gt;
&lt;td&gt;Token proxy — credentials never hit the browser&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;Upstash Redis (REST API)&lt;/td&gt;
&lt;td&gt;Serverless, Mumbai region, instant reads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment&lt;/td&gt;
&lt;td&gt;Vercel&lt;/td&gt;
&lt;td&gt;One &lt;code&gt;vercel&lt;/code&gt; command, done&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fonts&lt;/td&gt;
&lt;td&gt;Bebas Neue + DM Mono&lt;/td&gt;
&lt;td&gt;Race bib aesthetic — felt right for runners&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;The whole app is a single &lt;code&gt;index.html&lt;/code&gt; served from Vercel's CDN. All Redis commands go through a thin &lt;code&gt;/api/redis.js&lt;/code&gt; serverless function that proxies requests with an allow-list (&lt;code&gt;LRANGE&lt;/code&gt;, &lt;code&gt;LPUSH&lt;/code&gt;, &lt;code&gt;HGETALL&lt;/code&gt;, &lt;code&gt;HINCRBY&lt;/code&gt; only). The Upstash token never touches the browser.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Browser → /api/redis (Vercel Function) → Upstash Redis
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Redis schema:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;stride:cards&lt;/code&gt; — a Redis List. Each card is &lt;code&gt;LPUSH&lt;/code&gt;'d as JSON so &lt;code&gt;LRANGE 0 99&lt;/code&gt; always returns newest-first.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;stride:hypes&lt;/code&gt; — a Redis Hash. Each field is a card ID, value is the hype count. Incremented with &lt;code&gt;HINCRBY&lt;/code&gt; so concurrent hypes from different users don't collide.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hype counts are separated from card data intentionally — it means we never need to rewrite card JSON just to bump a counter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy Decisions
&lt;/h3&gt;

&lt;p&gt;One thing I thought carefully about was PII. A running community is a tight-knit group — real names on a public board felt uncomfortable.&lt;/p&gt;

&lt;p&gt;The solution:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Auto-generated nicknames&lt;/strong&gt; on load (20 adjectives × 20 animals × 90 numbers = 36,000 combos). No real name is ever suggested.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Anonymous mode&lt;/strong&gt; checkbox — posts as &lt;code&gt;🕶️ Anonymous Runner&lt;/code&gt;, the nickname is never sent to Redis at all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hypes are fully anonymous&lt;/strong&gt; — just a count in Redis, no user identity attached.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Zero PII hits the database either way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenges
&lt;/h3&gt;

&lt;p&gt;The trickiest part was deciding how to handle hype state across sessions. Since there's no auth, I used &lt;code&gt;sessionStorage&lt;/code&gt; to track "did this browser tab already hype this card" — which prevents double-hyping within a session without requiring login. It's a deliberate trade-off: refresh the page and you &lt;em&gt;can&lt;/em&gt; hype again, but that felt fine for a community hype board rather than a voting system.&lt;/p&gt;

&lt;p&gt;All writes are optimistic with rollback — the UI updates instantly and reverts if the Redis call fails.&lt;/p&gt;




&lt;h2&gt;
  
  
  Reflections
&lt;/h2&gt;

&lt;p&gt;I usually build side projects that solve &lt;em&gt;my&lt;/em&gt; problems. This one was different — I built it thinking about every runner who has a goal sitting in their head that they haven't told anyone yet.&lt;/p&gt;

&lt;p&gt;The first-timers who are terrified. The comeback runners who've been off for months with an injury. The sub-60 chasers who've been trying for years. They exist in every city, in every running community, at every race.&lt;/p&gt;

&lt;p&gt;StrideBoard is for all of them.&lt;/p&gt;

&lt;p&gt;Whatever your race, whatever your goal — drop it on the board. The community's got you. 🏃&lt;/p&gt;




&lt;p&gt;🙏 Thanks for reading! Would love any feedback or ideas in the comments.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>DevFlow: AI-Powered Git Workflow Automation with GitHub Copilot CLI</title>
      <dc:creator>Karthikeyan</dc:creator>
      <pubDate>Sat, 14 Feb 2026 05:42:05 +0000</pubDate>
      <link>https://dev.to/imkarthikeyan/devflow-ai-powered-git-workflow-automation-with-github-copilot-cli-247j</link>
      <guid>https://dev.to/imkarthikeyan/devflow-ai-powered-git-workflow-automation-with-github-copilot-cli-247j</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-01-21"&gt;GitHub Copilot CLI Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;I built &lt;strong&gt;DevFlow&lt;/strong&gt; - a CLI tool that automates your entire Git workflow using GitHub Copilot CLI as its AI brain. Think of it as your AI pair programmer that handles the boring parts of Git so you can focus on writing code.&lt;/p&gt;

&lt;p&gt;DevFlow does three things really well:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generates commit messages&lt;/strong&gt; from your changes using AI (no more "fix stuff" commits)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creates PR descriptions&lt;/strong&gt; automatically by analyzing your commits
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Names branches&lt;/strong&gt; semantically from GitHub issues&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The tool was born from a simple frustration: I spend way too much time crafting commit messages and PR descriptions. I wanted to automate this, but every existing tool either used generic templates or required me to write the message myself anyway. So I built DevFlow to actually &lt;em&gt;understand&lt;/em&gt; my code changes and generate meaningful descriptions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install it:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔗 GitHub: &lt;a href="https://github.com/karthik-zoro-96/devflow-cli" rel="noopener noreferrer"&gt;https://github.com/karthik-zoro-96/devflow-cli&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;📦 npm: &lt;a href="https://www.npmjs.com/package/git-devflow" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/git-devflow&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Smart Commit Messages
&lt;/h3&gt;

&lt;p&gt;Make your changes, run &lt;code&gt;devflow commit&lt;/code&gt;, and get 3 AI-generated conventional commit messages to choose from. Copilot analyzes your git diff and generates proper feat:/fix:/chore: messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Automated PR Descriptions
&lt;/h3&gt;

&lt;p&gt;Running &lt;code&gt;devflow pr create&lt;/code&gt; analyzes your commits, auto-pushes your branch, and creates a PR with a properly structured description including summary, changes, and testing notes.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Branch Naming from Issues
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;devflow branch create --issue 7&lt;/code&gt; fetches the GitHub issue and generates a semantic branch name like &lt;code&gt;feature/7-add-changelog-generation&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🤖 AI-powered commit message generation&lt;/li&gt;
&lt;li&gt;📝 Automatic PR description creation
&lt;/li&gt;
&lt;li&gt;🌿 Branch naming from GitHub issues or descriptions&lt;/li&gt;
&lt;li&gt;⚙️ AI model selection (Sonnet 4.5 / Haiku 4.5 / GPT-4.1)&lt;/li&gt;
&lt;li&gt;🔐 Secure token storage with 600 file permissions&lt;/li&gt;
&lt;li&gt;🚀 Auto-push branches before PR creation&lt;/li&gt;
&lt;li&gt;💰 Smart quota management with automatic free model fallback&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Experience with GitHub Copilot CLI
&lt;/h2&gt;

&lt;p&gt;Building DevFlow taught me that integrating with Copilot CLI isn't just about calling an API - it's about handling edge cases, quota limits, and shell escaping nightmares. Here's what I learned:&lt;/p&gt;

&lt;h3&gt;
  
  
  The Architecture: Copilot CLI as the Product
&lt;/h3&gt;

&lt;p&gt;Most people use Copilot CLI during development. I used it &lt;em&gt;as the product itself&lt;/em&gt;. Every DevFlow command pipes data to Copilot CLI and parses the response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;diff&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;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;diff&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;copilot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateCommitMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;diff&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;commits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parseResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple architecture, complex execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge #1: Shell Escaping Hell
&lt;/h3&gt;

&lt;p&gt;My first attempt at calling Copilot CLI looked innocent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;execSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`copilot -p "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This broke immediately. Why? Git diffs contain backticks, quotes, dollar signs, and every special character bash can interpret. The prompt would either fail to parse or, worse, execute unintended commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First attempt at fixing:&lt;/strong&gt; escape everything manually. Failed.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Second attempt:&lt;/strong&gt; write prompts to temp files. Better, but cluttered with file I/O.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final solution:&lt;/strong&gt; Use &lt;code&gt;execFileAsync&lt;/code&gt; with an args array instead of shell execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--model&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-s&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;--prompt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;execFileAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;copilot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;maxBuffer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60000&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 passes arguments directly to the Copilot binary without any shell interpretation. No escaping needed. Problem solved.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; When calling external CLIs with user data, never use shell execution. Always use the args array approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge #2: SSH Keys and Custom Hosts
&lt;/h3&gt;

&lt;p&gt;I have two GitHub accounts (work and personal) with different SSH keys. My personal SSH config uses a custom host alias:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host github-personal
  HostName github.com
  IdentityFile ~/.ssh/id_ed25519_personal
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;My git remote: &lt;code&gt;git@github-personal:user/repo.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;DevFlow's initial regex for parsing remotes: &lt;code&gt;git@github.com:user/repo.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; DevFlow couldn't find my repository!&lt;/p&gt;

&lt;p&gt;Every time I tried to create a PR, it failed with "Not a GitHub repository". I spent hours debugging before realizing the regex only matched the standard GitHub hostname.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The fix:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Handle ANY SSH host, not just github.com&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sshMatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/git@&lt;/span&gt;&lt;span class="se"&gt;([^&lt;/span&gt;&lt;span class="sr"&gt;:&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;:&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;.+&lt;/span&gt;&lt;span class="se"&gt;?)\/(&lt;/span&gt;&lt;span class="sr"&gt;.+&lt;/span&gt;&lt;span class="se"&gt;?)(\.&lt;/span&gt;&lt;span class="sr"&gt;git&lt;/span&gt;&lt;span class="se"&gt;)?&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sshMatch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sshMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;sshMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="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;strong&gt;Lesson:&lt;/strong&gt; Never assume standard configurations. Developers customize everything.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge #3: Quota Management
&lt;/h3&gt;

&lt;p&gt;Here's what nobody tells you about building with Copilot CLI: &lt;strong&gt;you'll hit quota limits constantly during development.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each test run consumed quota. I burned through my monthly allowance in two days of testing. When users hit limits, the tool would crash with cryptic errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My solution: Automatic fallback to free models&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;execWithQuotaRetry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getCopilotModel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// e.g., claude-sonnet-4.5&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execCopilotPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Detect quota errors&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isQuotaError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;⚠️  Premium request limit reached&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;   Retrying with gpt-4.1 (free)...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="c1"&gt;// Automatically retry with free model&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execCopilotPrompt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;gpt-4.1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the premium model fails due to quota, DevFlow automatically retries with GPT-4.1 (free tier). Users get a gentle warning and keep working. No crashes.&lt;/p&gt;

&lt;p&gt;I also added model cost visibility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="err"&gt;🤖&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;claude&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;sonnet&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;4.5&lt;/span&gt;  &lt;span class="nx"&gt;Balanced&lt;/span&gt;  &lt;span class="err"&gt;·&lt;/span&gt;  &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;premium&lt;/span&gt; &lt;span class="nf"&gt;request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;per&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Users can see exactly what they're spending before each request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; Plan for quota limits from day one. Free model fallbacks aren't nice-to-have, they're essential.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge #4: Parsing AI Responses
&lt;/h3&gt;

&lt;p&gt;Copilot CLI doesn't return structured JSON - it returns natural language text. Parsing this reliably is harder than it sounds.&lt;/p&gt;

&lt;p&gt;For commit messages, I asked for this format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. feat: add user authentication
2. fix: resolve login bug  
3. chore: update dependencies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What I got back varied wildly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sometimes numbered lists&lt;/li&gt;
&lt;li&gt;Sometimes markdown lists with &lt;code&gt;-&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Sometimes just sentences&lt;/li&gt;
&lt;li&gt;Sometimes with bold markdown &lt;code&gt;**&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;My solution: Multiple parsing strategies&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;parseCommitMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&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="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;for &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;line&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Try pattern 1: "1. message"&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;\d&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;[\.&lt;/span&gt;&lt;span class="sr"&gt;)&lt;/span&gt;&lt;span class="se"&gt;]\s&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;.+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;stripMarkdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;match&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="c1"&gt;// Try pattern 2: Direct conventional format&lt;/span&gt;
    &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;feat|fix|chore&lt;/span&gt;&lt;span class="se"&gt;)(\(&lt;/span&gt;&lt;span class="sr"&gt;.+&lt;/span&gt;&lt;span class="se"&gt;?\))?&lt;/span&gt;&lt;span class="sr"&gt;: .+/i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;stripMarkdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// Try pattern 3: "- message"&lt;/span&gt;
    &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;-*&lt;/span&gt;&lt;span class="se"&gt;]\s&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;.+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;stripMarkdown&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;match&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="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;strong&gt;Lesson:&lt;/strong&gt; AI output is unpredictable. Always have fallback parsing strategies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge #5: Silent Failures
&lt;/h3&gt;

&lt;p&gt;Copilot CLI sometimes fails with &lt;strong&gt;zero error output&lt;/strong&gt;. The process just exits with code 1 and nothing in stderr.&lt;/p&gt;

&lt;p&gt;This was a nightmare to debug. Users would see "unknown error" with no explanation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My solution: Read Copilot's log files&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nf"&gt;readLatestCopilotLog&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&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;logDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;homedir&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.copilot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;logs&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;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;readdirSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;logDir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;process-&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reverse&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;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;logDir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;files&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf-8&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;errorLines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;content&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="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="sr"&gt;ERROR&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="c1"&gt;// Return the actual error message&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;errorLines&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;errorLines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&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;When Copilot fails silently, DevFlow reads the most recent log file and extracts the actual error. This revealed authentication issues, model availability problems, and network errors that stderr didn't show.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lesson:&lt;/strong&gt; When stderr is empty, check log files. They often contain the real error.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Went Right
&lt;/h3&gt;

&lt;p&gt;Despite all the challenges, some things worked beautifully:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Copilot's natural language understanding&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I didn't need to fine-tune prompts extensively. "Generate 3 conventional commit messages" worked on the first try. The quality was genuinely impressive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The execFile approach&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Once I switched from shell execution to direct args passing, 90% of my bugs disappeared.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Fallback strategies&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Having rule-based fallbacks meant DevFlow never crashes. When AI fails, it falls back gracefully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Model cost transparency&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Showing users exactly what each request costs builds trust and helps them manage quota.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Stats
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;4 days&lt;/strong&gt; to build&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;15 quota limit errors&lt;/strong&gt; encountered and fixed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3 complete rewrites&lt;/strong&gt; of the SSH URL parser
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;~600 lines&lt;/strong&gt; of TypeScript&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;100% uptime&lt;/strong&gt; with fallbacks (never crashes)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  What I'd Do Differently
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Start with execFile from day one&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Don't waste time on shell escaping. Go straight to the args array approach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Build quota monitoring earlier&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I added model cost display as an afterthought. Should have been there from the start.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Test with weird SSH configs immediately&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I only discovered the custom host issue when deploying. Should have tested edge cases earlier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Read Copilot CLI docs twice&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
I missed useful flags and features because I skimmed the docs. RTFM saves time.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Magic Moment
&lt;/h3&gt;

&lt;p&gt;Despite all the debugging pain, there was one moment that made it all worth it:&lt;/p&gt;

&lt;p&gt;I ran &lt;code&gt;devflow pr create&lt;/code&gt; on a messy feature branch with 8 commits. Copilot analyzed them and generated this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Title: Add comprehensive README with features, setup, and usage guide

Summary:
Complete documentation overhaul transforming the minimal README into 
a comprehensive guide with branding, detailed instructions, and complete 
feature documentation.

Changes:
- Added DevFlow logo, tagline, and GitHub Copilot CLI Challenge badge
- Documented all 5 core features (commits, PRs, branches, config, auto-push)
- Added npm installation command and interactive setup instructions
- Comprehensive examples for all commands
- Explained how DevFlow uses Copilot CLI as its AI engine
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It was perfect. Better than I would have written myself. That's when I knew this tool was actually useful.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;GitHub Copilot CLI is excellent for natural language generation tasks. It's less excellent when you try to pipe complex, special-character-filled text through bash. But with proper error handling, quota management, and fallback strategies, you can build genuinely useful tools on top of it.&lt;/p&gt;

&lt;p&gt;The future of CLI tools is AI-powered. DevFlow is just the beginning.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Try DevFlow:&lt;/strong&gt; &lt;code&gt;npm install -g git-devflow&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Built with ❤️ using GitHub Copilot CLI.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>cli</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>Introducing Blog Stats Generator: Auto-Updating Blog Cards for Dev.to</title>
      <dc:creator>Karthikeyan</dc:creator>
      <pubDate>Sat, 16 Aug 2025 12:44:02 +0000</pubDate>
      <link>https://dev.to/imkarthikeyan/introducing-blog-stats-generator-auto-updating-blog-cards-for-devto-iom</link>
      <guid>https://dev.to/imkarthikeyan/introducing-blog-stats-generator-auto-updating-blog-cards-for-devto-iom</guid>
      <description>&lt;p&gt;Hello 👋,  &lt;/p&gt;

&lt;p&gt;I recently built a side project to showcase my Dev.to blogging stats — and it’s live on Product Hunt! 🚀  &lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;As someone who loves writing on Dev.to and tracking my blogging journey, I always wanted an easy way to showcase my progress — things like post counts, reactions, top tags, and more.&lt;/p&gt;

&lt;p&gt;So, I built &lt;strong&gt;Blog Stats Generator&lt;/strong&gt; 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Does
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📊 Generates auto-updating blog stats cards
&lt;/li&gt;
&lt;li&gt;🎨 Multiple themes (Default, Dev.to Light, Dracula, Night Owl, etc.)
&lt;/li&gt;
&lt;li&gt;🔗 Copy Markdown/HTML snippets to use in GitHub READMEs or blogs
&lt;/li&gt;
&lt;li&gt;✅ No login required — just enter your Dev.to username
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Why I Built It
&lt;/h2&gt;

&lt;p&gt;I wanted something simple and clean to:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Track my own blogging progress
&lt;/li&gt;
&lt;li&gt;Embed in my GitHub profile
&lt;/li&gt;
&lt;li&gt;Share milestones with my community
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It was also inspired by &lt;a href="https://github.com/anuraghazra/github-readme-stats" rel="noopener noreferrer"&gt;github-readme-stats&lt;/a&gt; built by &lt;a class="mentioned-user" href="https://dev.to/anuraghazra"&gt;@anuraghazra&lt;/a&gt;.  &lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;

&lt;p&gt;👉 Live app: &lt;a href="https://blog-stats-generator.vercel.app" rel="noopener noreferrer"&gt;https://blog-stats-generator.vercel.app&lt;/a&gt;&lt;br&gt;&lt;br&gt;
👉 GitHub Repo: &lt;a href="https://github.com/skarthikeyan96/blog-stats-generator" rel="noopener noreferrer"&gt;https://github.com/skarthikeyan96/blog-stats-generator&lt;/a&gt;  &lt;/p&gt;




&lt;h2&gt;
  
  
  Product Hunt Launch 🚀
&lt;/h2&gt;

&lt;p&gt;I’m super excited to share that I just launched this project on Product Hunt today!&lt;br&gt;&lt;br&gt;
If you find it useful, I’d love your support ❤️  &lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.producthunt.com/posts/blog-stats-generator" rel="noopener noreferrer"&gt;Check it out on Product Hunt&lt;/a&gt;  &lt;/p&gt;




&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Add the integration for Hashnode and Medium
&lt;/li&gt;
&lt;li&gt;More theme options
&lt;/li&gt;
&lt;li&gt;Shareable social previews
&lt;/li&gt;
&lt;/ol&gt;




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

&lt;p&gt;That’s it for now! I’d love to hear your feedback on the application in the comments 🙌.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>🧠 AI-Powered Quote Finder – Discover the Wisdom of Your Favorite Characters</title>
      <dc:creator>Karthikeyan</dc:creator>
      <pubDate>Sat, 26 Jul 2025 13:39:00 +0000</pubDate>
      <link>https://dev.to/imkarthikeyan/ai-powered-quote-finder-discover-the-wisdom-of-your-favorite-characters-k68</link>
      <guid>https://dev.to/imkarthikeyan/ai-powered-quote-finder-discover-the-wisdom-of-your-favorite-characters-k68</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/algolia-2025-07-09"&gt;Algolia MCP Server Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




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

&lt;p&gt;&lt;strong&gt;Quote Finder&lt;/strong&gt; is a lightning-fast, searchable archive of powerful quotes from anime, TV shows, games, and films. It helps fans rediscover iconic lines, explore character insights, and surface forgotten gems through a sleek UI powered by &lt;strong&gt;Algolia&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This project is a deeply personal one for me. I grew up immersed in anime — not just as entertainment, but as a wellspring of emotional depth, moral nuance, and philosophical reflection. From &lt;em&gt;One Piece&lt;/em&gt;’s freedom, to &lt;em&gt;Evangelion&lt;/em&gt;’s existential dread, anime taught me more about life than most textbooks ever could. &lt;strong&gt;Quote Finder&lt;/strong&gt; is my tribute to that universe.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;🔍 &lt;strong&gt;Instant Search&lt;/strong&gt; powered by Algolia&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;AI-Powered Tags &amp;amp; Sentiment&lt;/strong&gt; (e.g. "hope", "despair", "wisdom")&lt;/li&gt;
&lt;li&gt;❤️ &lt;strong&gt;Emotion Extraction&lt;/strong&gt; for deeper context&lt;/li&gt;
&lt;li&gt;🎭 &lt;strong&gt;Filter by Anime &amp;amp; Character&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;📱 &lt;strong&gt;Responsive &amp;amp; Mobile-First UI&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;💾 &lt;strong&gt;Built-in Favorites (via localStorage)&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: Next.js 15, React, TypeScript&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search&lt;/strong&gt;: Algolia Search API, InstantSearch.js&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Styling&lt;/strong&gt;: Tailwind CSS, Radix UI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Processing&lt;/strong&gt;: Sentiment &amp;amp; tag generation via GPT&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment&lt;/strong&gt;: Vercel&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Live Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live App&lt;/strong&gt;: &lt;a href="https://quote-search.vercel.app/" rel="noopener noreferrer"&gt;Quote Finder&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/skarthikeyan96/quote-search" rel="noopener noreferrer"&gt;github.com/skarthikeyan96/quote-search&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




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

&lt;h3&gt;
  
  
  🎬 Full-Text Search
&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.amazonaws.com%2Fuploads%2Farticles%2Fodp09pmggx3wv4q4gujt.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%2Fodp09pmggx3wv4q4gujt.png" alt="search" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🎭 Filter by Character or Anime
&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.amazonaws.com%2Fuploads%2Farticles%2F2jg8uzexdk6i7fniqk0u.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%2F2jg8uzexdk6i7fniqk0u.png" alt="anime" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  💬 Saving the quotes
&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.amazonaws.com%2Fuploads%2Farticles%2Fxl75cfwzpjfughslyjpm.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%2Fxl75cfwzpjfughslyjpm.png" alt="saving" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  📱 Fully Responsive
&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.amazonaws.com%2Fuploads%2Farticles%2Ffiwetzo65bxz21n90jr4.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%2Ffiwetzo65bxz21n90jr4.png" alt="responsive" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How I Used Algolia MCP Server
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Search Setup
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Configured a dedicated Algolia index with fine-tuned searchable attributes like &lt;code&gt;quote&lt;/code&gt;, &lt;code&gt;character&lt;/code&gt;, and &lt;code&gt;anime&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Integrated Algolia InstantSearch.js to handle real-time filtering and searching.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Dataset Design
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Custom-built a quote dataset from a mix of anime and fictional media.&lt;/li&gt;
&lt;li&gt;AI-tagged each quote with:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;sentiment_score&lt;/code&gt; (1–10)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sentiment_label&lt;/code&gt; (positive/neutral/negative)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tags&lt;/code&gt; (e.g. “truth”, “grief”, “purpose”)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;emotion&lt;/code&gt; (e.g. “inspiring”, “tragic”)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Search Experience
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Faceted filtering by character &amp;amp; anime&lt;/li&gt;
&lt;li&gt;Searchable fields: quote, anime, character, emotion, and tags&lt;/li&gt;
&lt;li&gt;Highlighted keywords in results&lt;/li&gt;
&lt;li&gt;LocalStorage-powered favorites&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Learnings &amp;amp; Challenges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🎭 Emotional Inference
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Challenge: How to assign emotion categories like “tragic” or “uplifting” without relying on external labels?&lt;/p&gt;

&lt;p&gt;Solution: Combined sentiment score + thematic tags to derive high-level emotions algorithmically.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  🗃️ Tag Consistency
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Challenge: Quotes ranged from poetic to deeply philosophical. Tags needed to be accurate and meaningful.&lt;/p&gt;

&lt;p&gt;Solution: Used GPT-4 to suggest tags based on meaning, not just keywords.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  💡 UX Refinement
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Challenge: Simple UI that honors the tone of the content.&lt;/p&gt;

&lt;p&gt;Solution: Minimalist card layout, soft gradients, and readable typography using Tailwind.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Technical Highlights
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Real-time search with InstantSearch.js&lt;/li&gt;
&lt;li&gt;Clean filter-based UI using Radix UI + Tailwind&lt;/li&gt;
&lt;li&gt;AI-derived metadata for nuanced discovery&lt;/li&gt;
&lt;li&gt;Fast, SEO-friendly static site via Next.js&lt;/li&gt;
&lt;li&gt;Highly scalable Algolia index structure&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ul&gt;
&lt;li&gt;🔒 User Accounts for cross-device saving&lt;/li&gt;
&lt;li&gt;🎞️ Add show scenes or visuals per quote&lt;/li&gt;
&lt;li&gt;📚 Expand to books, games, and films&lt;/li&gt;
&lt;li&gt;🧠 Improve emotion detection models&lt;/li&gt;
&lt;li&gt;📤 Allow user-submitted quotes&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Project Metrics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Quotes Indexed&lt;/strong&gt;: 200+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Characters Featured&lt;/strong&gt;: 50+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tags Generated&lt;/strong&gt;: 300+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bundle Size&lt;/strong&gt;: ~190 kB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lighthouse Score&lt;/strong&gt;: &amp;gt; 95&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;&lt;strong&gt;Quote Finder&lt;/strong&gt; is more than a search tool — it’s an emotional archive. It bridges my love for anime and my skills as a developer, turning nostalgia into a usable, searchable, and shareable tool.&lt;/p&gt;

&lt;p&gt;Whether you're a long-time anime fan or just someone looking for a quote that resonates — there's something here for you.&lt;/p&gt;




&lt;p&gt;🙏 Thank you for reading. Would love to hear your feedback or ideas!&lt;/p&gt;




</description>
      <category>devchallenge</category>
      <category>algoliachallenge</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>SnippetSearch: Code Snippets Discovery Engine for Developers</title>
      <dc:creator>Karthikeyan</dc:creator>
      <pubDate>Fri, 25 Jul 2025 21:43:09 +0000</pubDate>
      <link>https://dev.to/imkarthikeyan/snippetsearch-code-snippets-discovery-engine-for-developers-3gld</link>
      <guid>https://dev.to/imkarthikeyan/snippetsearch-code-snippets-discovery-engine-for-developers-3gld</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/algolia-2025-07-09"&gt;Algolia MCP Server Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




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

&lt;p&gt;&lt;strong&gt;SnippetSearch&lt;/strong&gt; is a comprehensive code snippet discovery and management platform built to help developers find, save, and organize useful code snippets from multiple sources. It aggregates content from Dev.to, Hashnode, CSS-Tricks, Smashing Magazine, and more using RSS and APIs, then enables a seamless search experience powered by &lt;strong&gt;Algolia&lt;/strong&gt;.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time Search:&lt;/strong&gt; Powered by Algolia InstantSearch.js&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-source Indexing:&lt;/strong&gt; Dev.to API, Hashnode RSS, CSS-Tricks, Smashing Magazine &amp;amp; more&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bookmarks:&lt;/strong&gt; Save your favorite snippets (persisted via localStorage)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart Tagging:&lt;/strong&gt; Automatic tag extraction from articles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile First:&lt;/strong&gt; Fully responsive interface&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean UI:&lt;/strong&gt; Built with Tailwind CSS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast &amp;amp; Optimized:&lt;/strong&gt; Minimal bundle size and fast builds&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: Next.js 15, React, TypeScript&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search&lt;/strong&gt;: Algolia Search API, InstantSearch.js&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Styling&lt;/strong&gt;: Tailwind CSS, Radix UI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Aggregation&lt;/strong&gt;: Custom RSS &amp;amp; API scrapers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deployment&lt;/strong&gt;: Vercel&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Live Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live App&lt;/strong&gt;: &lt;a href="https://dev-snippet-search.vercel.app" rel="noopener noreferrer"&gt;SnippetSearch&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/skarthikeyan96/dev-snippet-search" rel="noopener noreferrer"&gt;github.com/skarthikeyan96/dev-snippet-search&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Homepage&lt;/strong&gt;: Feature overview and clean hero section&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%2Fzhtyw5i90yi6tchz3odi.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%2Fzhtyw5i90yi6tchz3odi.png" alt="homepage" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Search Interface&lt;/strong&gt;: Filters, pagination, bookmark toggles&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%2F56ydm1z5t0b9gibs8usy.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%2F56ydm1z5t0b9gibs8usy.png" alt="search" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Bookmarks Modal&lt;/strong&gt;: Manage saved snippets&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%2Fbsvdr5lo5ofz9ap7ve7s.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%2Fbsvdr5lo5ofz9ap7ve7s.png" alt="Bookmarks" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mobile View&lt;/strong&gt;: Touch-optimized UI&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F769zty8tet02m5n59610.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%2F769zty8tet02m5n59610.png" alt="mobile" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;**Simple User analytics: 
&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%2Fljerjpc1pn0qp14h97qh.png" alt="analytics" width="800" height="517"&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How I Used Algolia MCP Server
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Search Infrastructure Setup
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Configured optimized indices with searchable attributes, highlighting, and ranking.&lt;/li&gt;
&lt;li&gt;Integrated InstantSearch.js with custom templates.&lt;/li&gt;
&lt;li&gt;Enabled search analytics to monitor user behavior.
### 2. Indexing Snippet Data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Parsed and indexed 388+ snippets from multiple sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dev.to API (324)&lt;/li&gt;
&lt;li&gt;Hashnode (32)&lt;/li&gt;
&lt;li&gt;CSS-Tricks (10)&lt;/li&gt;
&lt;li&gt;Smashing Magazine (10)&lt;/li&gt;
&lt;li&gt;Web Design Ledger (7)&lt;/li&gt;
&lt;li&gt;UX Movement (5)
Applied HTML cleaning and tag normalization.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Advanced Search Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Faceted filtering by source.&lt;/li&gt;
&lt;li&gt;Instant keyword highlighting.&lt;/li&gt;
&lt;li&gt;Custom pagination and mobile-friendly search interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Performance Optimizations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Reduced bundle size to ~224 kB.&lt;/li&gt;
&lt;li&gt;Implemented code splitting &amp;amp; vendor chunking.&lt;/li&gt;
&lt;li&gt;Optimized search rendering pipeline.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Learnings &amp;amp; Challenges
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Data Normalization
&lt;/h3&gt;

&lt;p&gt;Challenge: Varying formats across sources.&lt;br&gt;
Solution: HTML entity decoding + tag stripping.&lt;/p&gt;

&lt;h3&gt;
  
  
  UX in Search
&lt;/h3&gt;

&lt;p&gt;Challenge: Balancing speed and relevance.&lt;br&gt;
Solution: Custom ranking + highlighting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Responsive Design
&lt;/h3&gt;

&lt;p&gt;Challenge: Touch targets and layout flexibility.&lt;br&gt;
Solution: Tailwind utilities + mobile-first grid.&lt;/p&gt;

&lt;h3&gt;
  
  
  State Persistence
&lt;/h3&gt;

&lt;p&gt;Challenge: Bookmark state across reloads (without SSR issues).&lt;br&gt;
Solution: Hydration-safe localStorage management.&lt;/p&gt;




&lt;h2&gt;
  
  
  Technical Highlights
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Best practices for Algolia search tuning.&lt;/li&gt;
&lt;li&gt;Clean integration with InstantSearch.js templates.&lt;/li&gt;
&lt;li&gt;State hydration strategies for client-only features.&lt;/li&gt;
&lt;li&gt;Real-world TypeScript with Next.js.&lt;/li&gt;
&lt;li&gt;Tailwind for fast, maintainable UIs.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;ul&gt;
&lt;li&gt;Cloud sync for saved snippets&lt;/li&gt;
&lt;li&gt;User accounts + snippet sharing&lt;/li&gt;
&lt;li&gt;Code syntax highlighting&lt;/li&gt;
&lt;li&gt;Server-side rendering for SEO&lt;/li&gt;
&lt;li&gt;Offline-first PWA support&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Project Metrics
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Snippets Indexed&lt;/strong&gt;: 388+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sources Integrated&lt;/strong&gt;: 6+&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bundle Size&lt;/strong&gt;: 224 kB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile Friendly&lt;/strong&gt;: 100% responsive&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance&lt;/strong&gt;: Lighthouse score &amp;gt; 95&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;SnippetSearch showcases how Algolia's MCP Server can power a fast, elegant, and scalable search experience for developers. From content aggregation to real-time search, this project reflects the potential of modern tools when combined with thoughtful design and engineering.&lt;/p&gt;




&lt;p&gt;Thank you for reading. &lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>algoliachallenge</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>Nexus Dynamics - Frontend challenge</title>
      <dc:creator>Karthikeyan</dc:creator>
      <pubDate>Sun, 06 Jul 2025 11:10:32 +0000</pubDate>
      <link>https://dev.to/imkarthikeyan/nexus-dynamics-frontend-challenge-43ig</link>
      <guid>https://dev.to/imkarthikeyan/nexus-dynamics-frontend-challenge-43ig</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/frontend/axero"&gt;Frontend Challenge: Office Edition sponsored by Axero, Holistic Webdev: Office Space&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What I Built&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;I built a modern and interactive employee intranet portal for "Nexus Dynamics," designed as a central hub for essential information and tools. The layout prioritizes a clean, intuitive, and production-ready user experience, featuring a prominent header, real-time information, and a notification system. The main content is divided into two columns, showcasing company statistics, announcements, team spotlights, quick links, upcoming events, and office information. The design emphasizes visual appeal, readability, and ease of navigation, using custom SVG icons and a cohesive card-based layout.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Demo&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nexus-dynamics-99.netlify.app/" rel="noopener noreferrer"&gt;https://nexus-dynamics-99.netlify.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw1913jcilr5eri478bj2.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%2Fw1913jcilr5eri478bj2.png" alt="description" width="800" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Journey&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;My journey focused on building a robust frontend using HTML, CSS, and vanilla JavaScript. I meticulously structured the &lt;code&gt;index.html&lt;/code&gt;, applied modern styling with &lt;code&gt;styles.css&lt;/code&gt; for responsiveness and visual depth, and added interactivity using &lt;code&gt;script.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Key JavaScript features include a real-time clock, simulated dynamic data updates (notifications, weather, stats), and various click handlers for interactive elements. I also implemented a custom toast notification system and keyboard navigation shortcuts for enhanced usability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proudest Achievement: Dark Mode Implementation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm particularly proud of the comprehensive dark mode. This wasn't just a simple color inversion; it involved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A dedicated toggle button with dynamic icons.&lt;/li&gt;
&lt;li&gt;Persistence of user preference via &lt;code&gt;localStorage&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Automatic detection of system theme preference (&lt;code&gt;prefers-color-scheme&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Extensive styling adjustments across all UI elements in &lt;code&gt;styles.css&lt;/code&gt; to ensure optimal contrast and visual appeal in both light and dark themes.&lt;/li&gt;
&lt;li&gt;Smooth CSS transitions for a seamless theme switch.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project allowed me to explore vanilla frontend development, focusing on performance, accessibility, and user experience, with the dark mode implementation being a highlight that significantly enhanced the portal's modern appeal.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>frontendchallenge</category>
      <category>css</category>
      <category>javascript</category>
    </item>
    <item>
      <title>🧠 Mom Mode – Let Runner H Nag You into a Better Life</title>
      <dc:creator>Karthikeyan</dc:creator>
      <pubDate>Sun, 22 Jun 2025 13:52:15 +0000</pubDate>
      <link>https://dev.to/imkarthikeyan/mom-mode-let-runner-h-nag-you-into-a-better-life-34km</link>
      <guid>https://dev.to/imkarthikeyan/mom-mode-let-runner-h-nag-you-into-a-better-life-34km</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/runnerh"&gt;Runner H "AI Agent Prompting" Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;I created &lt;strong&gt;Mom Mode&lt;/strong&gt;, a funny automation that turns Runner H into your passive-aggressive AI mom. It sends daily reminders via email and Slack to check the weather, eat lunch, attend meetings, and drink water—nagging you with love to stay on track!&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Here’s Mom Mode in action:&lt;/p&gt;

&lt;p&gt;On June 22, 2025, at 06:52 PM IST, I got this hydration email:&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%2Ftxvkh6jmvg0alp42e992.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%2Ftxvkh6jmvg0alp42e992.png" alt="description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Logged messages in the Google Sheet:&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%2Fyerc6ogdumfhygcdl589.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%2Fyerc6ogdumfhygcdl589.png" alt="description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Runner-H demo: &lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/68rnrBxEorI"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  How I Used Runner H
&lt;/h2&gt;

&lt;p&gt;I tapped into Runner H’s scheduling, web scraping, and messaging features to create Mom Mode:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Weather Check&lt;/strong&gt;: Scrapes Google Weather for your place and sends an email.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meal Reminders&lt;/strong&gt;: Sends a Slack message at 2 PM IST.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calendar Check&lt;/strong&gt;: Checks Google Calendar and sends Slack meeting reminders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hydration Nudges&lt;/strong&gt;: Sends hourly email reminders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logging&lt;/strong&gt;: Logs messages in a Google Sheet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To replicate this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sign Up&lt;/strong&gt;: Get a Runner H account at runnerh.com.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Sheet&lt;/strong&gt;: Create a sheet with columns: Time, Message, Platform. Set to “Anyone with the link can edit.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Email&lt;/strong&gt;: Link your Gmail in Runner H.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slack&lt;/strong&gt;: Set up a channel or DM in Slack and connect it to Runner H.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calendar&lt;/strong&gt;: Link your Google Calendar (set to “View events”).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run the Prompt&lt;/strong&gt;: Use this in Runner H, replacing placeholders:&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;At 8 AM IST daily, check the weather for [your city] on Google Weather and send an email to [your email address] with a reminder like: "It’s [weather condition] today—did you bring [item, e.g., an umbrella], or are you asking for a cold?" At 2 PM IST, send a meal reminder via Slack to [your Slack channel or DM] with: "It’s 2 PM, no lunch yet? Do I need to cook for you?" Check my Google Calendar for meetings today and send a Slack reminder 30 minutes before each to [your Slack channel or DM] with: "You have a meeting at [time]—don’t make me look bad by being late!" Every hour from 9 AM to 6 PM IST, send a hydration reminder via email to [your email address] with: "Drink water now, or you’ll turn into a prune—love, Mom!" Log all messages sent (time, message, platform) in a Google Sheet [insert your Google Sheet link]. If a source is inaccessible, skip it and proceed.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  💡 Why It’s Special:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Turns a serious wellness use case into a funny, human experience.&lt;/li&gt;
&lt;li&gt;Requires &lt;strong&gt;no code&lt;/strong&gt;, just smart prompts and creativity.&lt;/li&gt;
&lt;li&gt;Makes healthy routines feel like love from home.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  💬 Testing Instructions:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Connect your &lt;strong&gt;Gmail&lt;/strong&gt;, &lt;strong&gt;Slack&lt;/strong&gt;, and &lt;strong&gt;Google Calendar&lt;/strong&gt; to Runner H.&lt;/li&gt;
&lt;li&gt;Use the prompt shared above (or tweak it to suit your mom’s "voice").&lt;/li&gt;
&lt;li&gt;Watch the magic — personalized, caring reminders like you’re living with your mom again (but digitally 😅).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thank you for reading. What do you think? Share your thoughts in the comments!&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>runnerhchallenge</category>
      <category>ai</category>
      <category>machinelearning</category>
    </item>
    <item>
      <title>Global TrendSpark: Automate Viral Content Creation with Runner H</title>
      <dc:creator>Karthikeyan</dc:creator>
      <pubDate>Sun, 15 Jun 2025 11:28:56 +0000</pubDate>
      <link>https://dev.to/imkarthikeyan/global-trendspark-automate-viral-content-creation-with-runner-h-2n2g</link>
      <guid>https://dev.to/imkarthikeyan/global-trendspark-automate-viral-content-creation-with-runner-h-2n2g</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/runnerh"&gt;Runner H "AI Agent Prompting" Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;I built &lt;strong&gt;Global TrendSpark&lt;/strong&gt;, an AI-powered pipeline that automates viral content creation. It uses Runner H to scrape global trends, draft SEO-optimized articles, schedule social media posts, send newsletters, and track everything in a Google Sheet—all with one prompt. This solves the problem of time-consuming content creation, helping creators stay ahead of trends effortlessly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Here’s Global TrendSpark in action:&lt;/p&gt;

&lt;p&gt;On June 15, 2025, at 3:12 PM IST, it sent this newsletter with trending topics:&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%2F4crfitrdad4rf4shedwd.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%2F4crfitrdad4rf4shedwd.png" alt="description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And logged the posts in a Google Sheet:&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%2Fntol7u1e8fzdo4fik5ti.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%2Fntol7u1e8fzdo4fik5ti.png" alt="description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Watch the workflow in action:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/UJJqv3EhNEg"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Runner H
&lt;/h2&gt;

&lt;p&gt;I leveraged Runner H’s web scraping, template filling, and multi-platform integration to automate the entire content pipeline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Trend Discovery&lt;/strong&gt;: Scrapes trends from Google Trends, X, Reddit (r/worldnews, r/technology), BBC, and CNN.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Article Generation&lt;/strong&gt;: Pulls a template from Google Docs and drafts 600-word articles with 3-5 SEO keywords.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Social Posting&lt;/strong&gt;: Schedules posts on X and LinkedIn with topic-specific hashtags.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Newsletter Sending&lt;/strong&gt;: Sends articles via Gmail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tracking&lt;/strong&gt;: Logs details in a Google Sheet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To replicate this, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sign Up&lt;/strong&gt;: Create a Runner H account at runnerh.com.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Article Template&lt;/strong&gt;: Create a Google Doc with a 5-section template (Introduction, Why It Matters, Key Developments, What’s Next, Conclusion). Set sharing to “Anyone with the link can view.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Sheet&lt;/strong&gt;: Create a Google Sheet with columns: Topic, Platform, Post Date, Article Link, Hashtags Used. Set sharing to “Anyone with the link can edit.”&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gmail Group&lt;/strong&gt;: In Gmail, create a contact group (e.g., “MyNewsletterSubs”).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run the Prompt&lt;/strong&gt;: Use this in Runner H, replacing placeholders:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search Google Trends, X, Reddit (r/worldnews, r/technology), BBC, and CNN for the top 3 global trending topics (tech, climate, or world events) from the last 24 hours. Pull my article template from Google Doc [insert your Google Doc link]. Draft a 600-word article for each topic, optimized for SEO with 3-5 trending keywords from the sources, following the template’s structure (Introduction, Why It Matters, Key Developments, What’s Next, Conclusion). Schedule posts on X and LinkedIn with 2-3 topic-specific hashtags (e.g., #AIRevolution for AI topics) and a caption like: “Discover the latest on [topic]! Read our new article: [link]. #[your project hashtag].” Compile articles into a newsletter with a subject line “[your project name]: Top Trends This Week,” embedding article links in the topic titles (e.g., “Technological Innovations”), and include a footer: “Follow us on X: [your X link] | LinkedIn: [your LinkedIn link].” Send via Gmail to my contact group [insert your Gmail contact group]. Log details (topic, platform, post date, article link, hashtags used) in a Google Sheet [insert your Google Sheet link]. If a source is inaccessible (e.g., paywall), skip it and proceed.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Test&lt;/strong&gt;: Verify trends are scraped, articles are generated, posts are scheduled, newsletters are sent, and the Google Sheet updates.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Use Case &amp;amp; Impact
&lt;/h2&gt;

&lt;p&gt;Global TrendSpark benefits content creators, marketers, and businesses by automating trend-based content creation. It’s perfect for bloggers targeting global audiences (5B+ internet users in 2025) or brands wanting to stay relevant. It saves hours of research and writing, boosts SEO with trending keywords, and increases engagement through timely posts. For example, a marketer can reach millions by sharing articles on “AI breakthroughs” or “climate tech” without manual effort.&lt;/p&gt;

&lt;p&gt;Thanks for checking out Global TrendSpark! What do you think? Share your thoughts in the comments! &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>devchallenge</category>
      <category>runnerhchallenge</category>
    </item>
    <item>
      <title>Building a GitHub Issue Auto-Labeler with Pulumi and Node.js: A Challenge Journey</title>
      <dc:creator>Karthikeyan</dc:creator>
      <pubDate>Sun, 06 Apr 2025 09:14:35 +0000</pubDate>
      <link>https://dev.to/imkarthikeyan/building-a-github-issue-auto-labeler-with-pulumi-and-nodejs-a-challenge-journey-3dnb</link>
      <guid>https://dev.to/imkarthikeyan/building-a-github-issue-auto-labeler-with-pulumi-and-nodejs-a-challenge-journey-3dnb</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/pulumi"&gt;Pulumi Deploy and Document Challenge&lt;/a&gt;: Get Creative with Pulumi and GitHub&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;I created the &lt;strong&gt;GitHub Issue Auto-Labeler&lt;/strong&gt;, a powerful tool that automates GitHub issue management using Pulumi and Node.js. This project labels issues in real-time based on keywords in their titles or descriptions, customizable via a &lt;code&gt;config.json&lt;/code&gt; file. It also posts friendly comments to remind contributors of guidelines and auto-closes stale issues after 30 days of inactivity. Built for the Pulumi Deploy and Document Challenge, it streamlines repository workflows, making it easier for maintainers and contributors alike to stay organized.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live Demo Link
&lt;/h2&gt;

&lt;p&gt;[Not applicable—local setup required]&lt;br&gt;&lt;br&gt;
&lt;em&gt;Note: This is a server-side tool requiring local deployment with &lt;code&gt;ngrok&lt;/code&gt;. Follow the README to set up and test locally. A hosted version is planned for the future.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Repo
&lt;/h2&gt;

&lt;p&gt;Check out the project on GitHub:&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/skarthikeyan96/issue-labeler" rel="noopener noreferrer"&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%2Fvzg54bovakfgcrqtby57.png" alt="Readme Card" width="442" height="108"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
The repository includes a detailed &lt;code&gt;README.md&lt;/code&gt; with installation steps, usage instructions, troubleshooting tips, and screenshots. The &lt;code&gt;docs/&lt;/code&gt; folder contains architecture notes, and the code is open for contributions—see &lt;a href="https://github.com/skarthikeyan96/issue-labeler/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;CONTRIBUTING.md&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Journey
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Process
&lt;/h3&gt;

&lt;p&gt;My 10-day journey began with setting up Node.js, Pulumi, and a GitHub repo. I used Express to create a webhook server and Octokit to interact with the GitHub API. The first challenge was getting the webhook to work—initial 404 errors with &lt;code&gt;ngrok&lt;/code&gt; were frustrating, but adding detailed logging (&lt;code&gt;console.log&lt;/code&gt; for requests) helped me pinpoint the issue (wrong URL path). Overcoming this, I implemented real-time labeling based on keywords, extending it to body content after testing with issue #10 ("Test bug issue").&lt;/p&gt;

&lt;p&gt;Adding configurable rules via &lt;code&gt;config.json&lt;/code&gt; was smooth, but integrating comments and stale issue closing added complexity. The comment feature required &lt;code&gt;client.issues.createComment&lt;/code&gt;, tested successfully on issue #13 ("Test enhancement #13"). For stale issues, I leveraged GitHub Actions with &lt;code&gt;actions/stale&lt;/code&gt;, configuring a 30-day inactivity threshold—tricky to test instantly, but the workflow is set.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenges
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Webhook Setup&lt;/strong&gt;: Misconfigured &lt;code&gt;ngrok&lt;/code&gt; URLs caused delays; I learned to double-check paths.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pulumi Labels&lt;/strong&gt;: Initial label creation failed due to missing tokens—fixed with proper environment setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time Management&lt;/strong&gt;: Balancing features across 10 days taught me to prioritize (labeling first, then enhancements).&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Debugging with logs is a lifesaver.&lt;/li&gt;
&lt;li&gt;Pulumi’s infrastructure-as-code approach simplifies label management.&lt;/li&gt;
&lt;li&gt;GitHub Actions complement server-side automation seamlessly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using Pulumi with GitHub
&lt;/h2&gt;

&lt;p&gt;Pulumi was the backbone of this project, enabling me to define and deploy GitHub labels as code. I used the &lt;code&gt;@pulumi/github&lt;/code&gt; package to create labels (&lt;code&gt;bug&lt;/code&gt;, &lt;code&gt;enhancement&lt;/code&gt;, &lt;code&gt;question&lt;/code&gt;) in my repo, ensuring consistency across environments. The &lt;code&gt;pulumi up&lt;/code&gt; command set up the infrastructure, which the Node.js server then leveraged via Octokit for dynamic labeling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Pulumi Was Beneficial
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automation&lt;/strong&gt;: Eliminated manual label creation, saving time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version Control&lt;/strong&gt;: Label definitions are tracked in Git, making changes reproducible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Easy to extend to multiple repos with Pulumi stacks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I didn’t use Pulumi Copilot, but if I had, a key prompt might have been:&lt;br&gt;&lt;br&gt;
&lt;em&gt;“Generate a Pulumi program to create GitHub labels ‘bug’, ‘enhancement’, and ‘question’ in my repo skarthikeyan96/issue-labeler.”&lt;/em&gt;&lt;br&gt;&lt;br&gt;
This would have accelerated the initial setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cover Image
&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.amazonaws.com%2Fuploads%2Farticles%2F682gbef10dd8n5bg8qs3.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%2F682gbef10dd8n5bg8qs3.png" alt="cover-image" width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A huge thanks to the Pulumi and Dev.to communities for this challenge! I’m excited to see where this project goes next! Star the repo at &lt;a href="https://github.com/skarthikeyan96/issue-labeler" rel="noopener noreferrer"&gt;https://github.com/skarthikeyan96/issue-labeler&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>pulumichallenge</category>
      <category>github</category>
      <category>api</category>
    </item>
    <item>
      <title>Understanding Graphs in JavaScript: Adjacency Matrix vs. Adjacency List</title>
      <dc:creator>Karthikeyan</dc:creator>
      <pubDate>Sun, 16 Feb 2025 18:50:38 +0000</pubDate>
      <link>https://dev.to/imkarthikeyan/understanding-graphs-in-javascript-adjacency-matrix-vs-adjacency-list-3kp2</link>
      <guid>https://dev.to/imkarthikeyan/understanding-graphs-in-javascript-adjacency-matrix-vs-adjacency-list-3kp2</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Graphs are one of the most fundamental data structures in computer science. They consist of nodes (also called vertices) connected by edges. Graphs are widely used in various real-world applications, such as social networks, navigation systems, and recommendation engines.&lt;/p&gt;

&lt;p&gt;In this post, we'll explore two common ways to represent graphs: &lt;strong&gt;Adjacency Matrix&lt;/strong&gt; and &lt;strong&gt;Adjacency List&lt;/strong&gt;. We'll also implement both representations in JavaScript and compare their efficiency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of Graph Representations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Adjacency Matrix
&lt;/h3&gt;

&lt;p&gt;An adjacency matrix is a 2D array (or matrix) that represents connections between nodes. If there is an edge between node &lt;code&gt;i&lt;/code&gt; and node &lt;code&gt;j&lt;/code&gt;, the matrix at position &lt;code&gt;[i][j]&lt;/code&gt; contains &lt;code&gt;1&lt;/code&gt; (or the weight of the edge, in case of weighted graphs). Otherwise, it contains &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Implementation in JavaScript
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Graph&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numNodes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matrix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;numNodes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;numNodes&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&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="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;addEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Edge already exists&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;removeEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;isEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;graph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Graph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEdge&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEdge&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;graph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;matrix&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/*
Output : 
[
  [0, 1, 1],
  [1, 0, 0],
  [1, 0, 0]
]
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Adjacency List
&lt;/h3&gt;

&lt;p&gt;An adjacency list represents a graph using a &lt;strong&gt;hash map (object in JavaScript)&lt;/strong&gt; where each key (node) stores an array of connected nodes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Implementation in JavaScript
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// adjacency list ( unweighted and undirected graph )&lt;/span&gt;
&lt;span class="cm"&gt;/**
 * {
  1: [2, 3],
  2: [1],
  3: [1]
}
 */&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AdjacencyList&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;addNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;]){&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; already exists`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;addEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`One or both nodes (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;) do not exist.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)){&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;removeEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;isEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//return this.list[from]?.includes(to) || false;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;indexOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newGraph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AdjacencyList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;newGraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNode&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="nx"&gt;newGraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;newGraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;newGraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEdge&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;newGraph&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEdge&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newGraph&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adjacency Matrix vs. Adjacency List - Edge Checking Differences
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Adjacency Matrix (2D Array)&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The matrix is a &lt;strong&gt;fixed-size 2D array&lt;/strong&gt; where we manually set both &lt;code&gt;matrix[from][to]&lt;/code&gt; and &lt;code&gt;matrix[to][from]&lt;/code&gt; to &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since we store edges explicitly in &lt;strong&gt;both directions&lt;/strong&gt;, checking both is necessary to ensure &lt;strong&gt;symmetry&lt;/strong&gt; in an undirected graph.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Example Matrix&lt;/strong&gt; for 3 nodes:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  0  1  2
0 [0, 1, 1]
1 [1, 0, 0]
2 [1, 0, 0]
&lt;/code&gt;&lt;/pre&gt;


&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;(0,1)&lt;/code&gt; exists, then &lt;code&gt;(1,0)&lt;/code&gt; &lt;strong&gt;must&lt;/strong&gt; also exist.&lt;/li&gt;
&lt;li&gt;The check ensures both positions are updated consistently.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Adjacency List (Object with Arrays)&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isEdge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;to&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;ul&gt;
&lt;li&gt;&lt;p&gt;The adjacency list stores edges in a &lt;strong&gt;single-directional way&lt;/strong&gt; (we manually push both &lt;code&gt;from → to&lt;/code&gt; and &lt;code&gt;to → from&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If &lt;code&gt;from&lt;/code&gt; contains &lt;code&gt;to&lt;/code&gt;, then &lt;code&gt;to&lt;/code&gt; will &lt;strong&gt;automatically&lt;/strong&gt; contain &lt;code&gt;from&lt;/code&gt;, because we add both at the same time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Example List&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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="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="mi"&gt;2&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="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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;ul&gt;
&lt;li&gt;If &lt;code&gt;0 → 1&lt;/code&gt; exists, then &lt;code&gt;1 → 0&lt;/code&gt; is &lt;strong&gt;already guaranteed&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;So, checking just one direction is enough.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Comparison: Adjacency Matrix vs. Adjacency List
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Adjacency Matrix&lt;/th&gt;
&lt;th&gt;Adjacency List&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Space Complexity&lt;/td&gt;
&lt;td&gt;O(V^2)&lt;/td&gt;
&lt;td&gt;O(V + E)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Checking an Edge&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;td&gt;O(V)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Adding an Edge&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Removing an Edge&lt;/td&gt;
&lt;td&gt;O(1)&lt;/td&gt;
&lt;td&gt;O(V)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for Dense Graphs&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best for Sparse Graphs&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adjacency Matrix&lt;/strong&gt; is great when the graph is &lt;strong&gt;dense&lt;/strong&gt; (many edges) since edge lookups are O(1).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adjacency List&lt;/strong&gt; is ideal for &lt;strong&gt;sparse&lt;/strong&gt; graphs as it requires less memory (O(V + E)).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real-World Applications of Graphs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Social Networks&lt;/strong&gt; (Facebook friends, LinkedIn connections)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Google Maps&lt;/strong&gt; (Finding the shortest route)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Recommendation Systems&lt;/strong&gt; (Netflix, Amazon product suggestions)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Both &lt;strong&gt;Adjacency Matrix&lt;/strong&gt; and &lt;strong&gt;Adjacency List&lt;/strong&gt; have their pros and cons. The choice depends on the use case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Use &lt;strong&gt;Adjacency Matrix&lt;/strong&gt; for &lt;strong&gt;dense graphs&lt;/strong&gt; where edge lookup speed is crucial.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;strong&gt;Adjacency List&lt;/strong&gt; for &lt;strong&gt;sparse graphs&lt;/strong&gt; where memory optimization matters.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Which approach do you prefer? Let me know in the comments! 🚀&lt;/p&gt;

&lt;p&gt;Thank you for reading! I hope this gave you a clear understanding of adjacency matrices and lists. In the next blog, we’ll dive into graph traversal techniques like BFS and DFS.&lt;/p&gt;

&lt;p&gt;💬 &lt;strong&gt;Let’s connect!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/karthik_coder" rel="noopener noreferrer"&gt;&lt;strong&gt;Twitter&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.instagram.com/coding_nemo" rel="noopener noreferrer"&gt;&lt;strong&gt;Instagram&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qckp9r4k7pmwqa13e03.gif" 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%2F2qckp9r4k7pmwqa13e03.gif" alt="final" width="500" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Top Tech Trends to Watch in 2025</title>
      <dc:creator>Karthikeyan</dc:creator>
      <pubDate>Mon, 06 Jan 2025 10:35:35 +0000</pubDate>
      <link>https://dev.to/imkarthikeyan/top-tech-trends-to-watch-in-2025-lam</link>
      <guid>https://dev.to/imkarthikeyan/top-tech-trends-to-watch-in-2025-lam</guid>
      <description>&lt;p&gt;Fun fact: The cover image was generated using AI!&lt;/p&gt;

&lt;p&gt;As we step into 2025, the tech landscape is gonna get a major refresh. The past year has been laying the groundwork for some awesome innovations, and now it's time to look ahead to the trends, tech, and tools that'll be making headlines. In this article, we'll dive into the future of tech and highlight the trends that'll shape the world of tomorrow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI: The Continued Rise to Awesomeness&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Artificial intelligence (AI) has been making some serious waves in the tech world. In 2025, we can expect AI to keep on trucking, changing the game for industries and transforming the way we live and work. From automating processes to supercharging analytics, AI will play a huge role in driving business decisions and making operations way more efficient.&lt;/p&gt;

&lt;p&gt;One area where AI will really make a difference is in natural language processing (NLP). As AI-powered chatbots and virtual assistants become more mainstream, we can expect to see some major advancements in language understanding, sentiment analysis, and text generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Emergence of Quantum Computing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Quantum computing is another area that's set to gain significant momentum in 2025. With the power to process complex calculations at insane speeds, quantum computing has the potential to solve some of the world's most pressing problems, from climate modeling to drug discovery. As quantum computing keeps evolving, we can expect to see some breakthroughs in medicine, finance, and materials science.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Extended Reality (XR): Redefining the Future of Interaction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Extended reality (XR) is gonna become way more mainstream in 2025. As XR tech gets even better, we can expect to see new use cases pop up in areas like education, entertainment, and healthcare.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Rise of 5G and Edge Computing&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With 5G networks rolling out everywhere, we'll get to enjoy faster data transfer rates, lower latency, and way more connectivity. This will supercharge the growth of edge computing, as data processing moves closer to the source. The combo of 5G and edge computing will enable a ton of new apps, from smart cities to autonomous vehicles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Web Development 2.0: A New Era of Building the Web&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In 2025, web development will undergo a significant transformation driven by emerging technologies like AI, blockchain, and XR. We can expect to see the rise of more secure, decentralized, and interactive web applications. AI-powered tools will revolutionize the way we design, develop, and maintain web applications, making the process more efficient and accessible to a wider range of people.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blockchain: Secure, Transparent, and Accountable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Blockchain tech will keep playing a vital role in keeping data secure and transparent. As more and more industries need transparent and accountable systems, we can expect to see blockchain get adopted way more widely in areas like supply chain management, voting systems, and identity verification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Internet of Bodies (IoB): A New Frontier&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Internet of Bodies (IoB) is all about the network of wearable devices, implants, and sensors that collect and transmit health-related data. In 2025, we can expect to see some major advancements in IoB, enabling new apps in health monitoring, disease diagnosis, and personalized medicine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cybersecurity: A Growing Concern&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As we rely more and more on tech, the threat of cyberattacks gets bigger. In 2025, cybersecurity will become an even bigger deal, with the need for way more sophisticated security measures to protect against threats like ransomware, phishing, and data breaches.&lt;/p&gt;

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

&lt;p&gt;As we look ahead to 2025, it's clear that the future of tech will be shaped by a combo of emerging trends, technologies, and tools. From AI and quantum computing to XR and blockchain, the next year will be all about innovations and advancements. As we embark on this journey, it's essential to stay informed, adapt to the changing landscape, and grab the opportunities that the future holds.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>newyearchallenge</category>
      <category>future</category>
    </item>
  </channel>
</rss>
