<?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: eddylee</title>
    <description>The latest articles on DEV Community by eddylee (@_a9b502091e5f4cba28f13).</description>
    <link>https://dev.to/_a9b502091e5f4cba28f13</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%2F3865783%2F565a111f-076c-45ed-a364-4ec2dd798edf.png</url>
      <title>DEV Community: eddylee</title>
      <link>https://dev.to/_a9b502091e5f4cba28f13</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_a9b502091e5f4cba28f13"/>
    <language>en</language>
    <item>
      <title>Why I Built a 4,000-Line Agent Skill Instead of Another npm Package</title>
      <dc:creator>eddylee</dc:creator>
      <pubDate>Tue, 07 Apr 2026 11:57:57 +0000</pubDate>
      <link>https://dev.to/_a9b502091e5f4cba28f13/why-i-built-a-4000-line-agent-skill-instead-of-another-npm-package-51la</link>
      <guid>https://dev.to/_a9b502091e5f4cba28f13/why-i-built-a-4000-line-agent-skill-instead-of-another-npm-package-51la</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;I use Claude Code (and sometimes Cursor) for frontend work every day. And every day, I fix the same mistakes:&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;// AI generates this&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks fine. TypeScript is happy. But &lt;code&gt;res.json()&lt;/code&gt; returns &lt;code&gt;any&lt;/code&gt; at runtime — if the API changes shape, this silently breaks in production.&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;// AI also loves this&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="kd"&gt;const&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="nx"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three separate pieces of state that can represent impossible combinations. &lt;code&gt;isLoading: true&lt;/code&gt; AND &lt;code&gt;data&lt;/code&gt; present? &lt;code&gt;error&lt;/code&gt; set but &lt;code&gt;isLoading&lt;/code&gt; still true?&lt;/p&gt;

&lt;p&gt;And my personal favorite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use client&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// slapped on the page component&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;ProductPage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...entire page is now client-rendered&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These aren't obscure edge cases. They happen constantly because AI agents don't have a structured reference for frontend TypeScript patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Not Just Fix It Each Time?
&lt;/h2&gt;

&lt;p&gt;I did. For months. Then I realized:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I'm correcting the same patterns over and over&lt;/li&gt;
&lt;li&gt;My corrections aren't persisted between sessions&lt;/li&gt;
&lt;li&gt;Every new conversation starts from zero&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I needed something the agent could &lt;strong&gt;read before generating code&lt;/strong&gt; — not a tutorial I'd paste into chat, but a structured reference it would consult automatically.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/leejpsd/typescript-react-patterns" rel="noopener noreferrer"&gt;typescript-react-patterns&lt;/a&gt;&lt;/strong&gt; — an Agent Skill for Claude Code, Cursor, Codex, and any AI tool that reads &lt;code&gt;SKILL.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;17 files. 4,000+ lines. Three directories:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;typescript-react-patterns/
├── SKILL.md              ← Hub: agent rules, decision guide, checklists
├── rules/                ← 11 pattern modules
│   ├── typescript-core.md
│   ├── react-typescript-patterns.md
│   ├── nextjs-typescript.md
│   ├── component-patterns.md
│   ├── data-fetching-and-api-types.md
│   ├── forms-and-validation.md
│   ├── state-management.md
│   ├── performance-and-accessibility.md
│   ├── debugging-checklists.md
│   ├── code-review-rules.md
│   └── anti-patterns.md
└── playbooks/            ← 3 debugging guides
    ├── type-error-debugging.md
    ├── hydration-issues.md
    └── effect-dependency-bugs.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What Makes This Different
&lt;/h2&gt;

&lt;p&gt;I've seen a lot of agent skills. Most are collections of code snippets. This one is designed as &lt;strong&gt;decision support&lt;/strong&gt; — helping the agent choose the right pattern, not just showing patterns.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Agent Behavior Rules
&lt;/h3&gt;

&lt;p&gt;The skill starts by telling the agent what to check &lt;em&gt;before&lt;/em&gt; writing any code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this server or client code?&lt;/li&gt;
&lt;li&gt;Is runtime validation needed? (Yes, if data comes from outside the app)&lt;/li&gt;
&lt;li&gt;What Next.js version? (&lt;code&gt;params&lt;/code&gt; is a Promise in 15+)&lt;/li&gt;
&lt;li&gt;What assumptions must NOT be made?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Decision Flowcharts
&lt;/h3&gt;

&lt;p&gt;Not just "here's a pattern" — but "when to use which":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is this data from a server/API?
├─ Yes → TanStack Query (NOT useState)
└─ No → Is it shareable via URL?
   ├─ Yes → searchParams
   └─ No → How many components need it?
      ├─ 1 → useState
      └─ Many → Zustand with selectors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Rule Classification
&lt;/h3&gt;

&lt;p&gt;Every rule is labeled:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;[HARD RULE]&lt;/strong&gt; — Violating causes bugs. No exceptions. &lt;em&gt;"Validate API responses at runtime."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[DEFAULT]&lt;/strong&gt; — Recommended unless you have a documented reason. &lt;em&gt;"Use interface for Props."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;[SITUATIONAL]&lt;/strong&gt; — Depends on context. &lt;em&gt;"Polymorphic components — only for design-system foundations."&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Before/After That Actually Matter
&lt;/h3&gt;

&lt;p&gt;Not toy examples. Real frontend scenarios:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;API typing:&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;// ❌ Before&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ After&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;email&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;infer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;userSchema&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&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;Loading state:&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;// ❌ Before — impossible states are representable&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setIsLoading&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&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="kd"&gt;const&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="nx"&gt;setError&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setData&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// ✅ After — impossible states are unrepresentable&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;idle&lt;/span&gt;&lt;span class="dl"&gt;'&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;'&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;T&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="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Debugging Playbooks
&lt;/h3&gt;

&lt;p&gt;When something goes wrong, the agent has step-by-step diagnosis guides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type errors&lt;/strong&gt;: Read bottom-up, classify, check common React/Next.js-specific errors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hydration mismatches&lt;/strong&gt;: Flowchart from symptom to fix (&lt;code&gt;useEffect&lt;/code&gt; vs &lt;code&gt;dynamic&lt;/code&gt; vs &lt;code&gt;Suspense&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;useEffect bugs&lt;/strong&gt;: Infinite loops (unstable deps), stale closures (captured state), missing cleanup&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Code Review Heuristics
&lt;/h3&gt;

&lt;p&gt;The skill distinguishes &lt;strong&gt;risk&lt;/strong&gt; (flag it) from &lt;strong&gt;preference&lt;/strong&gt; (mention it, don't block):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Risk:&lt;/strong&gt; &lt;code&gt;as&lt;/code&gt; on API data, &lt;code&gt;useEffect&lt;/code&gt; with object deps, server-only import in client component&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Preference:&lt;/strong&gt; &lt;code&gt;type&lt;/code&gt; vs &lt;code&gt;interface&lt;/code&gt;, handler naming convention, import ordering&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use It
&lt;/h2&gt;

&lt;p&gt;One command:&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/leejpsd/typescript-react-patterns ~/.claude/skills/typescript-react-patterns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent reads &lt;code&gt;SKILL.md&lt;/code&gt; automatically and consults the relevant &lt;code&gt;rules/&lt;/code&gt; file based on context. If you're working on a form, it reads &lt;code&gt;forms-and-validation.md&lt;/code&gt;. If there's a type error, it reads &lt;code&gt;playbooks/type-error-debugging.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Works with Claude Code, Cursor, Codex, Gemini CLI — anything that reads the &lt;code&gt;SKILL.md&lt;/code&gt; format.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Covered
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Module&lt;/th&gt;
&lt;th&gt;Topics&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TypeScript Core&lt;/td&gt;
&lt;td&gt;Narrowing, generics, utility types, &lt;code&gt;as const&lt;/code&gt;, &lt;code&gt;satisfies&lt;/code&gt;, &lt;code&gt;unknown&lt;/code&gt; vs &lt;code&gt;any&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;React Patterns&lt;/td&gt;
&lt;td&gt;Props, children, events, hooks, context, forwardRef, generic components&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Next.js&lt;/td&gt;
&lt;td&gt;App Router params, Server Actions, RSC boundaries, Edge, &lt;code&gt;useOptimistic&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Component Patterns&lt;/td&gt;
&lt;td&gt;Discriminated Props, compound components, modal/dialog, polymorphic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data Fetching&lt;/td&gt;
&lt;td&gt;Zod validation, TanStack Query, &lt;code&gt;Result&amp;lt;T,E&amp;gt;&lt;/code&gt;, pagination, error handling&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Forms&lt;/td&gt;
&lt;td&gt;react-hook-form + Zod, Server Actions, multi-step checkout example&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;State Management&lt;/td&gt;
&lt;td&gt;Decision matrix, Zustand (+ middleware), Context, URL state&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance &amp;amp; A11y&lt;/td&gt;
&lt;td&gt;Memoization tradeoffs, focus management, &lt;code&gt;aria-live&lt;/code&gt;, keyboard navigation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anti-patterns&lt;/td&gt;
&lt;td&gt;12 mistakes with symptoms, root causes, and fixes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;&lt;strong&gt;1. Structure matters more than volume.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Early versions had more files but less structure. The current version has fewer, denser modules with a consistent template: Scope → Key Rules → Examples → Anti-patterns → Review Checklist.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Agent skills need decision support, not just examples.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Showing 10 patterns is less useful than helping the agent &lt;em&gt;choose&lt;/em&gt; between them. Flowcharts and decision matrices are more valuable than code snippets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Classify your rules.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;[HARD RULE] vs [DEFAULT] vs [SITUATIONAL] changed everything. The agent stops treating every guideline as absolute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Cross-references prevent duplication.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every file has &lt;code&gt;See also&lt;/code&gt; links. The agent can navigate between modules without each file repeating everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contributing
&lt;/h2&gt;

&lt;p&gt;The skill is MIT-licensed and PRs are welcome. Priority areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Testing patterns (Vitest, Testing Library)&lt;/li&gt;
&lt;li&gt;Internationalization typing&lt;/li&gt;
&lt;li&gt;More debugging playbooks&lt;/li&gt;
&lt;li&gt;Accessibility deep dive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you try it and something is wrong or missing, open an issue. This is built to be iterated on.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/leejpsd/typescript-react-patterns" rel="noopener noreferrer"&gt;github.com/leejpsd/typescript-react-patterns&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install&lt;/strong&gt;: &lt;code&gt;git clone https://github.com/leejpsd/typescript-react-patterns ~/.claude/skills/typescript-react-patterns&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If this is useful, a ⭐ on GitHub helps others find it.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>react</category>
      <category>nextjs</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
