<?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: Manraj Sidhu</title>
    <description>The latest articles on Forem by Manraj Sidhu (@mannyss23).</description>
    <link>https://forem.com/mannyss23</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%2F3849967%2F41dd3679-1dc8-4f62-a864-95307aed04ed.jpg</url>
      <title>Forem: Manraj Sidhu</title>
      <link>https://forem.com/mannyss23</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mannyss23"/>
    <language>en</language>
    <item>
      <title>How I Shipped a Full-Stack Product in 30 Days With Claude Code, Linear, and Discord</title>
      <dc:creator>Manraj Sidhu</dc:creator>
      <pubDate>Sun, 29 Mar 2026 19:45:41 +0000</pubDate>
      <link>https://forem.com/mannyss23/how-i-shipped-a-full-stack-product-in-30-days-with-claude-code-linear-and-discord-5gi2</link>
      <guid>https://forem.com/mannyss23/how-i-shipped-a-full-stack-product-in-30-days-with-claude-code-linear-and-discord-5gi2</guid>
      <description>&lt;p&gt;I built a full-stack product in 30 days of evenings and weekends. Solo. Using Claude Code as my pair programmer, wired into Linear for ticket tracking and Discord for build notifications.&lt;/p&gt;

&lt;p&gt;The result: &lt;a href="https://pokemonvgcteamreport.com" rel="noopener noreferrer"&gt;VGC Team Report&lt;/a&gt; — a team report builder for competitive Pokemon (VGC). Players paste their teams and get detailed breakdowns with matchup plans, damage calcs, speed tiers, and shareable reports.&lt;/p&gt;

&lt;p&gt;This post is about the workflow — specifically how I connected Claude Code to Linear and Discord to create a one-person development pipeline that actually ships.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;274 commits in 30 days&lt;/li&gt;
&lt;li&gt;~42,000 lines of TypeScript&lt;/li&gt;
&lt;li&gt;25 features tracked and shipped via Linear&lt;/li&gt;
&lt;li&gt;66 React components, 41 API routes, 22 custom hooks&lt;/li&gt;
&lt;li&gt;Auth (Clerk), database (Neon Postgres), PWA, i18n in 7 languages&lt;/li&gt;
&lt;li&gt;Continuously deployed on Vercel&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js 16&lt;/strong&gt; (App Router)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;React 19&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript&lt;/strong&gt; (strict mode)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tailwind CSS v4&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clerk&lt;/strong&gt; for auth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Neon&lt;/strong&gt; for serverless Postgres&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vercel&lt;/strong&gt; for hosting and deploys&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linear&lt;/strong&gt; for ticket tracking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Discord&lt;/strong&gt; for build notifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code&lt;/strong&gt; as the AI development partner&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Workflow: Linear -&amp;gt; Claude -&amp;gt; Discord -&amp;gt; Vercel
&lt;/h2&gt;

&lt;p&gt;This is what a typical session looks like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Claude runs &lt;code&gt;linear_get_in_progress&lt;/code&gt; to check my Linear board for tickets&lt;/li&gt;
&lt;li&gt;Picks the highest priority ticket (bugs first, always)&lt;/li&gt;
&lt;li&gt;Reads relevant files and implements the feature or fix&lt;/li&gt;
&lt;li&gt;Runs &lt;code&gt;tsc --noEmit &amp;amp;&amp;amp; npm run build&lt;/code&gt; — if it fails, Claude fixes the errors&lt;/li&gt;
&lt;li&gt;Commits with the ticket ID: &lt;code&gt;VGC-42: Add speed tier chart&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Pushes to main&lt;/li&gt;
&lt;li&gt;Posts a comment on the Linear ticket via GraphQL — commit URL + changed files&lt;/li&gt;
&lt;li&gt;Moves the ticket to In Review&lt;/li&gt;
&lt;li&gt;Calls &lt;code&gt;discord_notify_build&lt;/code&gt; — posts an embed to Discord #builds with the commit, changed file list, and deploy status&lt;/li&gt;
&lt;li&gt;Vercel auto-deploys from main&lt;/li&gt;
&lt;li&gt;Moves to the next ticket&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This isn't hypothetical. I wrote a &lt;code&gt;linear.sh&lt;/code&gt; bash script with functions that Claude calls directly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;linear_get_in_progress&lt;/code&gt; — queries Linear GraphQL for In Progress tickets&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;linear_move_issue&lt;/code&gt; — moves a ticket to a new state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;linear_comment_with_changes&lt;/code&gt; — posts a comment with the commit link and changed files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;discord_notify_build&lt;/code&gt; — sends a Discord embed with commit info and deploy status&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Claude calls these via bash. The whole flow — implement, verify, commit, update Linear, notify Discord — happens in one session without me touching any of those systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  The CLAUDE.md Operating Manual
&lt;/h2&gt;

&lt;p&gt;The key to making this work is a &lt;code&gt;CLAUDE.md&lt;/code&gt; file at the repo root. Claude reads it at the start of every session. Mine contains:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Git strategy:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trunk-based development — push direct to main for routine work&lt;/li&gt;
&lt;li&gt;Feature branches only for large or risky changes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;npx tsc --noEmit &amp;amp;&amp;amp; npm run build&lt;/code&gt; before every push — non-negotiable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Linear workflow:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The exact state IDs for "In Progress" and "In Review"&lt;/li&gt;
&lt;li&gt;How to query for tickets, implement them, commit with the VGC-XX prefix&lt;/li&gt;
&lt;li&gt;How to post the commit comment and move the ticket state&lt;/li&gt;
&lt;li&gt;Rule: bug tickets are always worked on first, regardless of priority number&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Discord notifications:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;discord_notify_build&lt;/code&gt; function format&lt;/li&gt;
&lt;li&gt;Different embeds for direct-to-main pushes vs PR flows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Failure handling:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build fails → fix and retry, never push broken code&lt;/li&gt;
&lt;li&gt;Linear API fails → still commit and push, note the failure to the user&lt;/li&gt;
&lt;li&gt;Production breaks → &lt;code&gt;git revert&lt;/code&gt;, push to main, notify Discord, move ticket back&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Code conventions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Follow existing patterns, no drive-by refactors&lt;/li&gt;
&lt;li&gt;Commit messages: &lt;code&gt;VGC-XX: description&lt;/code&gt; for tracked work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This file is the single most valuable thing in the project. Every session starts with full context. No re-explaining, no drift, no "can you check the codebase structure?"&lt;/p&gt;

&lt;h2&gt;
  
  
  Automated Monitoring
&lt;/h2&gt;

&lt;p&gt;Beyond the dev workflow, I set up two Vercel cron jobs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Daily (9 AM):&lt;/strong&gt; Site health check, stale ticket scan, SEO audit, DB health — posts alerts to Discord only if something's wrong&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Weekly (Friday 5 PM):&lt;/strong&gt; Linear progress digest, user growth, dependency updates — always posts a summary to Discord&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These run on Vercel's free tier. Real-time uptime monitoring is handled by UptimeRobot with 5-minute pings.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Worked
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Trunk-based development with type-checking gates.&lt;/strong&gt; Every push to main auto-deploys on Vercel. The gatekeeper is &lt;code&gt;tsc --noEmit &amp;amp;&amp;amp; npm run build&lt;/code&gt;. The feedback loop is minutes, not days.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linear ticket traceability.&lt;/strong&gt; Every commit links back to a ticket. Every ticket has a comment with the commit URL and changed files. When something breaks, I trace it to the exact change and the exact intent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Discord as an audit trail.&lt;/strong&gt; Every build posts to #builds. It sounds like overkill for a solo project, but scrolling through the channel to see what shipped this week is genuinely useful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The CLAUDE.md as living infrastructure.&lt;/strong&gt; I update it whenever the workflow changes. New conventions, new failure modes, new scripts — they go in the file. The tool gets better over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Didn't Work
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CSS and visual design.&lt;/strong&gt; Claude produces functional layouts but doesn't have design taste. I make all the visual decisions and often rewrite styling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Debugging hydration and timing issues.&lt;/strong&gt; Race conditions, hydration mismatches, animation timing — Claude is better at implementing known patterns than diagnosing novel bugs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linear GraphQL escaping.&lt;/strong&gt; Nested JSON in bash curl commands was unreliable. I had to build the helper script with proper escaping to make it work consistently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Letting the CLAUDE.md go stale.&lt;/strong&gt; If I didn't update it for a few days, output quality dropped. The file needs maintenance like any other infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Takeaways
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The bottleneck for a solo developer isn't writing code.&lt;/strong&gt; It's maintaining context across sessions and keeping momentum. A good CLAUDE.md and a wired-up workflow solve this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vibe coding without guardrails produces slop.&lt;/strong&gt; Vibe coding with type-checking gates, ticket traceability, and automated deploys produces a real product. The engineering isn't in the typing — it's in the system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI doesn't replace engineering judgment — it amplifies it.&lt;/strong&gt; The decisions about what to build, how to structure it, and when to ship are still yours. The tools let you act on those decisions faster.&lt;/p&gt;

&lt;p&gt;30 days. Evenings and weekends. One engineer with Claude, Linear, and Discord. A product people are actually using.&lt;/p&gt;

&lt;p&gt;Check it out: &lt;a href="https://pokemonvgcteamreport.com" rel="noopener noreferrer"&gt;pokemonvgcteamreport.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>showdev</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
