<?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>Forem: sanjay kumar</title>
    <description>The latest articles on Forem by sanjay kumar (@sanjay_kumar_584).</description>
    <link>https://forem.com/sanjay_kumar_584</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%2F1607576%2F6a90ef5c-e7a2-4f1a-adb4-60495c5bf299.png</url>
      <title>Forem: sanjay kumar</title>
      <link>https://forem.com/sanjay_kumar_584</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sanjay_kumar_584"/>
    <language>en</language>
    <item>
      <title>Turborepo vs Regular Monorepo: When It's Worth It (And When It's Not)</title>
      <dc:creator>sanjay kumar</dc:creator>
      <pubDate>Mon, 19 Jan 2026 16:32:44 +0000</pubDate>
      <link>https://forem.com/sanjay_kumar_584/turborepo-vs-regular-monorepo-when-its-worth-it-and-when-its-not-38fl</link>
      <guid>https://forem.com/sanjay_kumar_584/turborepo-vs-regular-monorepo-when-its-worth-it-and-when-its-not-38fl</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn4g9k2whlasxld87zqen.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%2Fn4g9k2whlasxld87zqen.png" alt=" " width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  📦 &lt;strong&gt;Turborepo vs. Regular Repos: When It Helps — and When It’s Overkill&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Modern JS/TS projects often grow into multiple packages — maybe a backend, a frontend, shared UI components, and utilities. At that point you face a choice:&lt;/p&gt;

&lt;p&gt;➡️ Stick to separate repos (or a basic monorepo)&lt;br&gt;
➡️ Add tooling like &lt;strong&gt;Turborepo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s break down what you gain (and lose) with each.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🌐 What Regular Repos / Basic Monorepos Look Like&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With multiple separate repos (or a raw monorepo without tooling), each package manages its own:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build scripts&lt;/li&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;li&gt;Dependency installs&lt;/li&gt;
&lt;li&gt;CI pipelines&lt;/li&gt;
&lt;li&gt;Versioning&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simple mental model&lt;/li&gt;
&lt;li&gt;Lower setup cost&lt;/li&gt;
&lt;li&gt;Works for small teams / small projects&lt;/li&gt;
&lt;li&gt;No new tooling required&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repeated installs (&lt;code&gt;npm install&lt;/code&gt; everywhere)&lt;/li&gt;
&lt;li&gt;Repeated builds&lt;/li&gt;
&lt;li&gt;Harder to share common code&lt;/li&gt;
&lt;li&gt;CI takes longer&lt;/li&gt;
&lt;li&gt;Coordination pain when projects depend on each other&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setup tends to break down once people start reusing internal components or libraries.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;⚡ What Turborepo Brings to the Table&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Turborepo is a build system for JavaScript/TypeScript monorepos with features like:&lt;/p&gt;

&lt;p&gt;✔ Caching — skip repeated builds/tests&lt;br&gt;
✔ Parallel execution — run tasks across packages&lt;br&gt;
✔ Remote cache (Vercel) — great for teams&lt;br&gt;
✔ Pipeline orchestration — define dependencies (&lt;code&gt;build → test → lint&lt;/code&gt;)&lt;br&gt;
✔ Zero config for common setups (Next.js, React, etc.)&lt;/p&gt;

&lt;p&gt;That means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;build&lt;/code&gt; becomes fast&lt;/li&gt;
&lt;li&gt;CI stops wasting cycles doing repeated work&lt;/li&gt;
&lt;li&gt;Local iteration improves a lot when switching branches&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;👨‍👩‍👧 Team &amp;amp; Scale — The Key Decision&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Where Turborepo shines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple apps + shared UI libs&lt;/li&gt;
&lt;li&gt;Long CI pipelines&lt;/li&gt;
&lt;li&gt;Teams with 3+ engineers&lt;/li&gt;
&lt;li&gt;Repeated tasks between packages&lt;/li&gt;
&lt;li&gt;Next.js projects (native support is great)&lt;/li&gt;
&lt;li&gt;Component libraries&lt;/li&gt;
&lt;li&gt;Microfrontends / microservices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example setups that benefit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dashboard + marketing + shared-ui&lt;/li&gt;
&lt;li&gt;backend + frontend + shared-types&lt;/li&gt;
&lt;li&gt;API + worker + CLI + shared config&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;💥 Where Turborepo Is Overkill&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This is the part people underestimate.&lt;/p&gt;

&lt;p&gt;Turborepo is too heavy if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have just one app&lt;/li&gt;
&lt;li&gt;No shared components/libs&lt;/li&gt;
&lt;li&gt;Builds/tests are already fast&lt;/li&gt;
&lt;li&gt;CI cost isn’t a pain point&lt;/li&gt;
&lt;li&gt;Solo developer moving fast&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also overkill if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You don’t plan for growth&lt;/li&gt;
&lt;li&gt;You don’t need cross-repo orchestration&lt;/li&gt;
&lt;li&gt;You don’t care about remote caching&lt;/li&gt;
&lt;/ul&gt;

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

&lt;blockquote&gt;
&lt;p&gt;"React frontend + basic Node backend with no shared code"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can run it as two repos or a single folder without tooling and life is fine.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;🔧 Dev Productivity Angle&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criteria&lt;/th&gt;
&lt;th&gt;Regular Repos&lt;/th&gt;
&lt;th&gt;Turborepo&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Setup Complexity&lt;/td&gt;
&lt;td&gt;⭐ Easy&lt;/td&gt;
&lt;td&gt;⚠️ Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaling&lt;/td&gt;
&lt;td&gt;😬 Painful&lt;/td&gt;
&lt;td&gt;⭐ Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI Time&lt;/td&gt;
&lt;td&gt;Slow&lt;/td&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev Experience&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;Polished&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learning Curve&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Low-Medium&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tooling Overhead&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Some&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Team Benefit&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;📈 When It Starts Feeling Worth It&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you start hitting these symptoms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Duplicate dependencies&lt;/li&gt;
&lt;li&gt;“Why is CI so slow?”&lt;/li&gt;
&lt;li&gt;“Build is taking forever”&lt;/li&gt;
&lt;li&gt;Shared types between backend/frontend&lt;/li&gt;
&lt;li&gt;Releasing packages becomes manual work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then Turborepo feels like turning on a cheat code.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;📝 Final Take&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use Turborepo if:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You care about DX + CI performance + shared workspace between multiple packages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Skip it if:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You’re building solo, have a single app, or don’t feel coordination pain yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tools should remove friction — not add ceremony.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Networking Mistakes That Cost Me 6 Months</title>
      <dc:creator>sanjay kumar</dc:creator>
      <pubDate>Sat, 03 Jan 2026 07:31:11 +0000</pubDate>
      <link>https://forem.com/sanjay_kumar_584/what-i-learned-about-networking-after-doing-it-wrong-for-a-long-time-395e</link>
      <guid>https://forem.com/sanjay_kumar_584/what-i-learned-about-networking-after-doing-it-wrong-for-a-long-time-395e</guid>
      <description>&lt;h1&gt;
  
  
  What I Learned About Networking and Building Credibility (After Doing It Wrong)
&lt;/h1&gt;

&lt;p&gt;For a long time, I believed that &lt;strong&gt;skills alone were enough&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If I built good things, learned fast, and shared my work, I thought opportunities and networks would naturally follow. So I joined communities, connected with people on LinkedIn, tried cold outreach, and kept posting what I was building.&lt;/p&gt;

&lt;p&gt;What I got was a lot of &lt;strong&gt;connections&lt;/strong&gt; — but very little &lt;strong&gt;real network&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;These are the most important things I learned from that experience.&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%2Fc9mz4s596q1s5v1pjm05.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%2Fc9mz4s596q1s5v1pjm05.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Communities give connections, not networks
&lt;/h2&gt;

&lt;p&gt;I joined many communities hoping to “network”.&lt;/p&gt;

&lt;p&gt;Most of them turned out to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;memes&lt;/li&gt;
&lt;li&gt;generic posts&lt;/li&gt;
&lt;li&gt;shallow discussions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I realized something important:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A community is only valuable if you can &lt;strong&gt;contribute&lt;/strong&gt; to it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Without contribution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;there’s no trust&lt;/li&gt;
&lt;li&gt;no memory&lt;/li&gt;
&lt;li&gt;no real relationship&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Communities create &lt;em&gt;connections&lt;/em&gt; by default.&lt;br&gt;
They only become &lt;em&gt;networks&lt;/em&gt; when you add value.&lt;/p&gt;

&lt;p&gt;That’s why smaller, focused spaces — like open-source projects or builder-driven ecosystems — are far more useful than large generic communities.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Showing skills is not the same as adding value
&lt;/h2&gt;

&lt;p&gt;I used to showcase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what I built&lt;/li&gt;
&lt;li&gt;what I learned&lt;/li&gt;
&lt;li&gt;what I was capable of&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But people don’t really care about &lt;strong&gt;what you’ve done&lt;/strong&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;what problem you can help them solve&lt;/li&gt;
&lt;li&gt;what pain you can reduce &lt;em&gt;right now&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Skills are &lt;strong&gt;potential value&lt;/strong&gt;.&lt;br&gt;
Solving someone’s real problem is &lt;strong&gt;actual value&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once I understood this, my approach changed completely.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Cold outreach rarely works (especially early)
&lt;/h2&gt;

&lt;p&gt;I tried cold emails and DMs where I explained my skills and experience.&lt;/p&gt;

&lt;p&gt;Very few replies.&lt;/p&gt;

&lt;p&gt;Not because people were rude — but because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;founders already have networks&lt;/li&gt;
&lt;li&gt;senior engineers are busy&lt;/li&gt;
&lt;li&gt;generic outreach is just noise&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cold outreach only works when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the problem is extremely specific&lt;/li&gt;
&lt;li&gt;timing is perfect&lt;/li&gt;
&lt;li&gt;value is obvious immediately&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That combination is rare.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Random commenting is forgettable
&lt;/h2&gt;

&lt;p&gt;I also tried commenting everywhere to “stay visible”.&lt;/p&gt;

&lt;p&gt;That didn’t work either.&lt;/p&gt;

&lt;p&gt;What &lt;em&gt;does&lt;/em&gt; work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;extending someone’s idea&lt;/li&gt;
&lt;li&gt;adding a missing perspective&lt;/li&gt;
&lt;li&gt;sharing a concrete insight from your own experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If a comment doesn’t add value, it’s forgotten instantly.&lt;/p&gt;

&lt;p&gt;Networks are built on &lt;strong&gt;recall&lt;/strong&gt;, not reach.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. You must know where &lt;em&gt;you&lt;/em&gt; can provide value
&lt;/h2&gt;

&lt;p&gt;Another mistake I made was trying to be everywhere.&lt;/p&gt;

&lt;p&gt;Now I ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What do I actually know well?&lt;/li&gt;
&lt;li&gt;Who does this help?&lt;/li&gt;
&lt;li&gt;Where does this matter?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Networking becomes easier when you stop asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“How do I connect with people?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and start asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Where can I be genuinely useful?”&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  6. Platforms matter more than we think
&lt;/h2&gt;

&lt;p&gt;Different platforms reward different kinds of content.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dev.to works best for &lt;strong&gt;clear, accessible technical ideas&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;very complex or deep work often gets less reach&lt;/li&gt;
&lt;li&gt;YouTube favors entertainment and storytelling&lt;/li&gt;
&lt;li&gt;LinkedIn favors narrative and social proof&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I once shared work that was too complex for the platform and got almost no engagement.&lt;/p&gt;

&lt;p&gt;It wasn’t bad work — it was &lt;strong&gt;platform mismatch&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Understanding the audience matters as much as the content.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Think from the founder’s perspective
&lt;/h2&gt;

&lt;p&gt;One mental shift helped me a lot:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If I were a founder with credibility and a strong network, how would I view a random inbound message?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most founders:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;already know talented people&lt;/li&gt;
&lt;li&gt;don’t urgently need help&lt;/li&gt;
&lt;li&gt;optimize for signal, not curiosity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So instead of asking for attention, it’s far more effective to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;contribute to their product&lt;/li&gt;
&lt;li&gt;improve documentation&lt;/li&gt;
&lt;li&gt;fix a bug&lt;/li&gt;
&lt;li&gt;extend their ideas publicly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s how cold connections slowly become warm.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;What I learned is simple, but not easy:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Networking isn’t about being skilled.&lt;br&gt;
It’s about being useful — in the right context, at the right time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’m still learning this, but understanding the difference between &lt;strong&gt;connections&lt;/strong&gt; and &lt;strong&gt;networks&lt;/strong&gt; completely changed how I approach building credibility.&lt;/p&gt;

</description>
      <category>marketing</category>
      <category>networking</category>
      <category>career</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Built Real-Time Voice AI in 3 Days (YC Interview)</title>
      <dc:creator>sanjay kumar</dc:creator>
      <pubDate>Tue, 23 Dec 2025 04:03:10 +0000</pubDate>
      <link>https://forem.com/sanjay_kumar_584/building-a-real-time-voice-ai-system-for-a-yc-style-assessment-25j3</link>
      <guid>https://forem.com/sanjay_kumar_584/building-a-real-time-voice-ai-system-for-a-yc-style-assessment-25j3</guid>
      <description>&lt;h3&gt;
  
  
  Freya Voice AI Agent Console (Forward-Deployed Engineering Deep Dive)
&lt;/h3&gt;

&lt;p&gt;As part of a &lt;strong&gt;YC-style technical assessment&lt;/strong&gt;, I built &lt;strong&gt;Freya Voice AI Agent Console&lt;/strong&gt; — a &lt;strong&gt;production-grade, real-time voice-to-voice AI system&lt;/strong&gt; focused on low latency, clean architecture, and real-world constraints.&lt;/p&gt;

&lt;p&gt;The goal wasn’t just to “make it work”, but to design something that feels &lt;strong&gt;forward-deployable&lt;/strong&gt;: a system you could realistically ship, iterate on, and operate.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;Source code:&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/05sanjaykumar/Freya-Voice-YC25-Assessment" rel="noopener noreferrer"&gt;https://github.com/05sanjaykumar/Freya-Voice-YC25-Assessment&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 What Was Built
&lt;/h2&gt;

&lt;p&gt;Freya is a &lt;strong&gt;real-time conversational voice AI&lt;/strong&gt; that supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bidirectional &lt;strong&gt;voice-to-voice conversations&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Sub-200ms latency streaming&lt;/li&gt;
&lt;li&gt;Prompt versioning via a web console&lt;/li&gt;
&lt;li&gt;Session metrics and analytics&lt;/li&gt;
&lt;li&gt;Fully Dockerized deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project was built in &lt;strong&gt;3 days&lt;/strong&gt;, prioritizing &lt;strong&gt;voice pipelines over chat UIs&lt;/strong&gt;, similar to real YC engineering evaluations.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔊 Voice AI Pipeline (End-to-End)
&lt;/h2&gt;

&lt;p&gt;The core pipeline looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;User speaks&lt;/strong&gt; → audio streamed via WebRTC&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech-to-Text (STT)&lt;/strong&gt; → Groq Whisper&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LLM reasoning&lt;/strong&gt; → Groq LLaMA-3.1-8B&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text-to-Speech (TTS)&lt;/strong&gt; → Cartesia Sonic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Audio streamed back&lt;/strong&gt; to the user in real time&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To improve accuracy and latency:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Silero VAD&lt;/strong&gt; detects speech boundaries&lt;/li&gt;
&lt;li&gt;Audio chunks are processed incrementally&lt;/li&gt;
&lt;li&gt;Responses are streamed, not buffered&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This architecture mirrors how modern voice assistants are built in production.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏗️ System Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[ Browser Client ]
     ↓ WebRTC (LiveKit)
[ Next.js Frontend ]
     ↓ HTTP / WS
[ Python Voice Agent ]
     ↓
[ Groq (STT + LLM) ] → [ Cartesia (TTS) ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why LiveKit?
&lt;/h3&gt;

&lt;p&gt;LiveKit handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WebRTC negotiation&lt;/li&gt;
&lt;li&gt;Low-latency audio routing&lt;/li&gt;
&lt;li&gt;Session lifecycle management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This avoids re-implementing complex real-time networking logic — a key &lt;strong&gt;forward-deployed engineering decision&lt;/strong&gt;.&lt;/p&gt;




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

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

&lt;ul&gt;
&lt;li&gt;Next.js 15 (App Router)&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Tailwind CSS&lt;/li&gt;
&lt;li&gt;LiveKit Client SDK&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Python 3.11&lt;/li&gt;
&lt;li&gt;LiveKit Agents&lt;/li&gt;
&lt;li&gt;Groq APIs (Whisper + LLaMA)&lt;/li&gt;
&lt;li&gt;Cartesia TTS&lt;/li&gt;
&lt;li&gt;Silero VAD&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Infrastructure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker &amp;amp; Docker Compose&lt;/li&gt;
&lt;li&gt;Multi-service orchestration&lt;/li&gt;
&lt;li&gt;Health checks &amp;amp; env-based config&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Prompt Management &amp;amp; Observability
&lt;/h2&gt;

&lt;p&gt;Freya includes a lightweight &lt;strong&gt;prompt management system&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create &amp;amp; version prompts&lt;/li&gt;
&lt;li&gt;Edit prompts without restarting sessions&lt;/li&gt;
&lt;li&gt;Track which prompt version was used per conversation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Session metrics include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Duration&lt;/li&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Active connections&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are essential when deploying AI agents into real customer environments.&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Running Locally
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/05sanjaykumar/Freya-Voice-YC25-Assessment
&lt;span class="nb"&gt;cd &lt;/span&gt;Freya-Voice-YC25-Assessment
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.example .env
docker compose up &lt;span class="nt"&gt;--build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Visit: &lt;code&gt;http://localhost:3000&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You’ll need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;LiveKit credentials&lt;/li&gt;
&lt;li&gt;Groq API key&lt;/li&gt;
&lt;li&gt;Cartesia API key&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 Engineering Tradeoffs (YC-Style)
&lt;/h2&gt;

&lt;p&gt;Some deliberate decisions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Voice-first over chat:&lt;/strong&gt; harder, but closer to real-world systems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In-memory storage:&lt;/strong&gt; faster iteration, easier debugging&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service boundaries early:&lt;/strong&gt; frontend, agent, and infra separated from day one&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker everywhere:&lt;/strong&gt; reproducibility &amp;gt; local hacks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These choices optimize for &lt;strong&gt;clarity, deployability, and iteration speed&lt;/strong&gt; — not just demos.&lt;/p&gt;




&lt;h2&gt;
  
  
  🛣️ What I’d Build Next
&lt;/h2&gt;

&lt;p&gt;If this were going to production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PostgreSQL + Redis for state&lt;/li&gt;
&lt;li&gt;Horizontal agent scaling&lt;/li&gt;
&lt;li&gt;CI/CD (GitHub Actions)&lt;/li&gt;
&lt;li&gt;OpenTelemetry for tracing&lt;/li&gt;
&lt;li&gt;Session replay &amp;amp; recording&lt;/li&gt;
&lt;li&gt;Rate limiting &amp;amp; abuse prevention&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;This project was less about “AI magic” and more about &lt;strong&gt;engineering judgment&lt;/strong&gt;:&lt;br&gt;
latency, reliability, real-time systems, and clean abstractions.&lt;/p&gt;

&lt;p&gt;If you’re preparing for &lt;strong&gt;YC-style interviews, Forward Deployed Engineer roles, or real-time AI systems&lt;/strong&gt;, I hope this serves as a practical reference.&lt;/p&gt;

&lt;p&gt;Happy building 🚀&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>devops</category>
      <category>programming</category>
    </item>
    <item>
      <title>Extract GitHub Folders in 1 Command (No Clone)</title>
      <dc:creator>sanjay kumar</dc:creator>
      <pubDate>Fri, 04 Jul 2025 11:09:11 +0000</pubDate>
      <link>https://forem.com/sanjay_kumar_584/i-built-a-cli-tool-to-extract-folders-or-files-from-github-repos-making-things-easier-in-a-single-3e3o</link>
      <guid>https://forem.com/sanjay_kumar_584/i-built-a-cli-tool-to-extract-folders-or-files-from-github-repos-making-things-easier-in-a-single-3e3o</guid>
      <description>&lt;h1&gt;
  
  
  🚀 Solving GitHub Folder Extraction with Go — A CLI for Real-World Git Edge Cases
&lt;/h1&gt;

&lt;p&gt;Cloning a full GitHub repo when you only need one folder or file is overkill — especially with monorepos.&lt;/p&gt;

&lt;p&gt;I wanted a simple CLI tool that lets me extract just a folder from any GitHub repo. Sounds simple, right?&lt;/p&gt;

&lt;p&gt;It’s not. GitHub’s structure, especially with &lt;strong&gt;branches that have slashes in their names&lt;/strong&gt;, makes this problem deceptively tricky. Here's how I solved it — and why the hard part wasn’t syntax or boilerplate, but reasoning through ambiguity.&lt;/p&gt;




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

&lt;p&gt;Let’s say you have this URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
[https://github.com/supabase/storage/tree/fix/pgboss-on-error-callback/src/http/plugins](https://github.com/supabase/storage/tree/fix/pgboss-on-error-callback/src/http/plugins)

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;You want just the &lt;code&gt;src/http/plugins&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;But &lt;code&gt;fix/pgboss-on-error-callback&lt;/code&gt; is the branch name — and it has slashes in it.&lt;/li&gt;
&lt;li&gt;So how do you distinguish the &lt;strong&gt;branch name&lt;/strong&gt; from the &lt;strong&gt;folder path&lt;/strong&gt;?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where traditional methods like &lt;code&gt;git sparse-checkout&lt;/code&gt; break down unless you know the exact branch and folder manually.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔧 My Solution: GitSlice CLI
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://github.com/05sanjaykumar/gitslice" rel="noopener noreferrer"&gt;GitSlice&lt;/a&gt;, a Go CLI tool that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Accepts a GitHub folder or file URL&lt;/li&gt;
&lt;li&gt;Parses and resolves the correct &lt;strong&gt;branch&lt;/strong&gt; and &lt;strong&gt;path&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Clones only the required data&lt;/li&gt;
&lt;li&gt;Extracts it into your current directory
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gitslice https://github.com/supabase/storage/tree/fix/pgboss-on-error-callback/src/http/plugins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧪 The Hardest Part: Branch vs Path Resolution
&lt;/h2&gt;

&lt;p&gt;GitHub doesn’t give you the branch and folder explicitly — just a single URL. So I had to build a resolver that intelligently distinguishes between them.&lt;/p&gt;

&lt;p&gt;Here’s how I approached it:&lt;/p&gt;

&lt;h3&gt;
  
  
  🧠 Step-by-Step Path Resolution Logic
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Clone the Repository (Sparse Mode):
&lt;/h4&gt;

&lt;p&gt;GitSlice starts by shallow cloning the entire repo into a temporary folder (e.g., cloneTemp). This avoids full history and keeps things lightweight&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Parse the GitHub URL into Parts:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postTree = ['fix', 'pgboss-on-error-callback', 'src', 'http', 'plugins']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Inspect the Local Folder After Clone:
&lt;/h4&gt;

&lt;p&gt;After cloning, we list the folder structure at the root of the repo. This gives us the actual directories present at that commit.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Smart Matching to Infer the Real Path:
&lt;/h4&gt;

&lt;p&gt;Now we iterate through postTree, trying different splits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;First, assume the first n parts of postTree could be the branch name.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The remaining parts are then assumed to be the path within the repo.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At each step, we check if the path exists on disk. If it does, we lock that in as the correct branch/path combo.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Example Matching:
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="n"&gt;github_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="sr"&gt;/supabase/storage/tree/fix/pgboss-on-error-callback/src/http/&lt;/span&gt;&lt;span class="n"&gt;plugins&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;GitSlice tries:
Branch = &lt;code&gt;fix&lt;/code&gt;, Path = &lt;code&gt;pgboss-on-error-callback/src/http/plugins&lt;/code&gt; → Not found
Branch = &lt;code&gt;fix/pgboss-on-error-callback&lt;/code&gt;, Path = &lt;code&gt;src/http/plugins&lt;/code&gt; → ✅ Match&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  6. Handle Nested Branch Names Intelligently:
&lt;/h4&gt;

&lt;p&gt;This means GitSlice doesn’t rely on hardcoded assumptions or magic string slicing. Instead, it lets the filesystem be the truth.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧩 Step-by-Step Logic
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Parse the post-&lt;code&gt;tree&lt;/code&gt; part of the URL
&lt;/h4&gt;

&lt;p&gt;From a URL like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://github.com/user/repo/tree/branch-name/src/plugins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Split it into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;postTree&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;fix&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pgboss&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;on&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Clone the repo to a temp dir
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone &lt;span class="nt"&gt;--filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;blob:none &lt;span class="nt"&gt;--no-checkout&lt;/span&gt; https://github.com/user/repo cloneTemp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Compare folder structure to detect real path
&lt;/h4&gt;

&lt;p&gt;I implemented this logic in &lt;code&gt;resolveBranchAndPath()&lt;/code&gt; in internal/clone/clone.go file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;resolveBranchAndPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clonePath&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;postTree&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;postTree&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;branchCandidate&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;postTree&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;pathCandidate&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;postTree&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pathCandidate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;fullPath&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clonePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filepath&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pathCandidate&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="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Stat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fullPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsDir&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;branchCandidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;strings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pathCandidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="no"&gt;nil&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="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Errorf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"❌ Could not resolve branch/path. Check if URL or folders exist"&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 method tries &lt;strong&gt;all possible splits&lt;/strong&gt; of the post-tree part and validates whether the resulting folder exists in the cloned repo. It worked across many real-world repos with complex branch names.&lt;/p&gt;




&lt;h2&gt;
  
  
  🐍 Pseudocode (Pythonic Version)
&lt;/h2&gt;

&lt;p&gt;Just for clarity, here's the rough equivalent logic in pseudocode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;github_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;github.com/supabase/storage/tree/fix/pgboss-on-error-callback/src/http/plugins&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;local_after_clone&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;storage/src/http/plugins&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="c1"&gt;# Split the URL and detect where 'tree' starts
&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;github_url&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;tree&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;base_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;post_tree&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&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;break&lt;/span&gt;

&lt;span class="c1"&gt;# Now try matching folder structure
&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;post_tree&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;post_tree&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;local_after_clone&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="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;branch_candidate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post_tree&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;path_candidate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;post_tree&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;:]&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧠 Why I Used AI (And Why That’s Fine)
&lt;/h2&gt;

&lt;p&gt;Yes, I used AI to assist with some parts — like refreshing Go syntax or generating boilerplate for CLI args. But the &lt;strong&gt;real problem-solving&lt;/strong&gt; — like figuring out branch-path ambiguity, recursive folder matching, and edge case debugging — was 100% me.&lt;/p&gt;

&lt;p&gt;AI didn’t know how to solve this. It only accelerated parts of the process — like a calculator helps with math, but doesn’t understand the problem.&lt;/p&gt;




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

&lt;p&gt;With Go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go &lt;span class="nb"&gt;install &lt;/span&gt;github.com/05sanjaykumar/gitslice@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or clone and build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/05sanjaykumar/gitslice
&lt;span class="nb"&gt;cd &lt;/span&gt;gitslice
go build &lt;span class="nt"&gt;-o&lt;/span&gt; gitslice main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🛠️ Usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gitslice &amp;lt;github-folder-or-file-url&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gitslice https://github.com/supabase/storage/tree/fix/pgboss-on-error-callback/src/auth
gitslice https://github.com/vercel/next.js/tree/canary/packages/next
gitslice https://github.com/05sanjaykumar/Flappy-Bird-OpenCV/blob/main/assets/background-day.png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🆚 GitSlice vs Manual Git Steps
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;With GitSlice&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;gitslice https://github.com/user/repo/tree/branch/folder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Manually&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;git clone &lt;span class="nt"&gt;--filter&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;blob:none &lt;span class="nt"&gt;--sparse&lt;/span&gt; https://github.com/user/repo
&lt;span class="nb"&gt;cd &lt;/span&gt;repo
git sparse-checkout init &lt;span class="nt"&gt;--cone&lt;/span&gt;
git sparse-checkout &lt;span class="nb"&gt;set &lt;/span&gt;folder
git checkout branch
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; folder ../
&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GitSlice reduces 7 steps to 1 — and eliminates the guesswork.&lt;/p&gt;




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

&lt;p&gt;This project taught me how even basic-sounding ideas hide a surprising amount of technical complexity. Let me know your thoughts or how you'd approach it differently!&lt;/p&gt;

&lt;p&gt;🔗 &lt;a href="https://github.com/05sanjaykumar/gitslice" rel="noopener noreferrer"&gt;GitSlice GitHub Repo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Made By Sanjay Kumar
&lt;/h3&gt;

</description>
      <category>go</category>
      <category>opensource</category>
      <category>cli</category>
      <category>github</category>
    </item>
    <item>
      <title>How I Built a URL Shortener Using Node.js, Redis, Docker &amp; Deployed It on Render</title>
      <dc:creator>sanjay kumar</dc:creator>
      <pubDate>Sat, 24 May 2025 10:30:50 +0000</pubDate>
      <link>https://forem.com/sanjay_kumar_584/how-i-built-a-url-shortener-using-nodejs-redis-docker-deployed-it-on-render-3g9d</link>
      <guid>https://forem.com/sanjay_kumar_584/how-i-built-a-url-shortener-using-nodejs-redis-docker-deployed-it-on-render-3g9d</guid>
      <description>&lt;p&gt;👋 A Quick Backstory&lt;br&gt;
Hey everyone, I’m Sanjay — a self-taught dev who loves building from scratch and learning by doing. I recently went deep into DevOps and containerization, and this URL shortener project was my way of exploring Redis, Docker, and cloud deployment — all in one shot.&lt;/p&gt;

&lt;p&gt;This project was never about just shortening URLs. For me, it was about:&lt;/p&gt;

&lt;p&gt;Learning how to structure a scalable backend 🧱&lt;/p&gt;

&lt;p&gt;Working with Redis as a primary data store 🧠&lt;/p&gt;

&lt;p&gt;Deploying real-world projects with Docker + Render 🚀&lt;/p&gt;

&lt;p&gt;It’s simple on the surface, but I learned a ton building this. Here's the breakdown 👇&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%2Fvwj3tln5zvg6nj5v1ofz.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%2Fvwj3tln5zvg6nj5v1ofz.png" alt="Preview Image" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔗 URL Shortener – Node.js, Redis &amp;amp; Docker
&lt;/h2&gt;

&lt;p&gt;A full-stack, production-grade URL shortening service built with &lt;strong&gt;Node.js&lt;/strong&gt;, &lt;strong&gt;Express&lt;/strong&gt;, &lt;strong&gt;Redis&lt;/strong&gt;, and &lt;strong&gt;Docker&lt;/strong&gt; — complete with a RESTful API, unit tests, containerization, and cloud deployment on Render.&lt;/p&gt;




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

&lt;blockquote&gt;
&lt;p&gt;🟢 Deployed on &lt;a href="https://url-shortern-9qxj.onrender.com/" rel="noopener noreferrer"&gt;Render&lt;/a&gt;&lt;br&gt;
Frontend: Static &lt;code&gt;HTML + JS&lt;/code&gt;&lt;br&gt;
Backend: Node.js + Redis&lt;br&gt;
Dockerized with &lt;code&gt;Dockerfile&lt;/code&gt; and &lt;code&gt;nginx&lt;/code&gt; (for local use)&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: HTML, JavaScript (Vanilla)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Node.js + Express&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt;: Redis (for storing shortened URLs)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing&lt;/strong&gt;: Jest&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DevOps&lt;/strong&gt;: Docker, Render, NGINX&lt;br&gt;
(Experimental): Rate Limiting, GitHub Actions (CI)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker &amp;amp; docker-compose (for local development)&lt;/li&gt;
&lt;li&gt;Render (for cloud deployment)&lt;/li&gt;
&lt;li&gt;NGINX (proxy for local routing)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;05sanjaykumar-url-shortern/
├── public/             # Static frontend (HTML + JS)
├── src/
│   ├── app.js          # Main app setup
│   ├── controllers/    # Shorten &amp;amp; redirect logic
│   ├── middleware/     # Rate limiting (dummy)
│   ├── routes/         # API endpoints
│   └── services/       # Redis logic + URL generation
├── test/               # Unit tests + Redis mocks
├── nginx/              # NGINX config (for local Docker)
├── .github/workflows/  # CI pipeline (placeholder)
├── Dockerfile + docker-compose.yml
├── server.js
└── .env-example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;ul&gt;
&lt;li&gt;🔗 Shortens long URLs to unique 6-character codes&lt;/li&gt;
&lt;li&gt;🚀 Redirects to original URLs&lt;/li&gt;
&lt;li&gt;🧠 Stores URL mappings in &lt;strong&gt;Redis&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🧪 Unit-tested with mocked Redis interactions&lt;/li&gt;
&lt;li&gt;🛠️ Includes a &lt;strong&gt;basic demo rate limiter&lt;/strong&gt; (not production-grade)&lt;/li&gt;
&lt;li&gt;🐳 Local Docker support&lt;/li&gt;
&lt;li&gt;🌐 Fully deployed backend + frontend on &lt;strong&gt;Render&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚙️ Running Locally
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Option 1: Docker (recommended)
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;p&gt;Then open: localhost&lt;/p&gt;

&lt;p&gt;(OR)&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2: Manual
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout render-deploy
npm &lt;span class="nb"&gt;install
&lt;/span&gt;redis-server
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open: &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 Run Tests
&lt;/h2&gt;



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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Tests include mocked Redis functionality for isolated unit testing.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  📦 Deployment (Render)
&lt;/h2&gt;

&lt;p&gt;The app is deployed using &lt;strong&gt;Render&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Backend connects to Redis&lt;/li&gt;
&lt;li&gt;Frontend served statically (via nginx or Render)&lt;/li&gt;
&lt;li&gt;Base URL is dynamically handled in production&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📌 Learnings
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📦 Designed modular Express backend (routes, controllers, services)&lt;/li&gt;
&lt;li&gt;🧪 Wrote unit tests with Redis mocks&lt;/li&gt;
&lt;li&gt;🐳 Containerized with Docker + Docker Compose&lt;/li&gt;
&lt;li&gt;🚀 Deployed on Render (frontend + backend)&lt;/li&gt;
&lt;li&gt;🛠️ Explored how rate limiting works in Express &lt;em&gt;(demo-only)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;🌱 Gained deeper insight into app structure, devops, and deployment&lt;/li&gt;
&lt;/ul&gt;




&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;Note&lt;/strong&gt;: The rate limiter is a basic, demonstration-only middleware. For real-world production use, consider packages like &lt;code&gt;express-rate-limit&lt;/code&gt; or Redis-backed implementations.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🙌 Author
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Sanjay Kumar&lt;/strong&gt; — &lt;em&gt;Lifelong learner, and builder of things.&lt;/em&gt;&lt;br&gt;
&lt;a href="https://github.com/05sanjaykumar/URL-shortern" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;&lt;/p&gt;

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