<?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: Moukie</title>
    <description>The latest articles on DEV Community by Moukie (@moukie_6e50335af6c9733592).</description>
    <link>https://dev.to/moukie_6e50335af6c9733592</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4053184%2F6e74c2a5-7871-4f57-a7b7-84aec2abe6d1.png</url>
      <title>DEV Community: Moukie</title>
      <link>https://dev.to/moukie_6e50335af6c9733592</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/moukie_6e50335af6c9733592"/>
    <language>en</language>
    <item>
      <title>Stop explaining your stack to Cursor in every new chat (use .cursor/rules instead)</title>
      <dc:creator>Moukie</dc:creator>
      <pubDate>Wed, 29 Jul 2026 14:17:04 +0000</pubDate>
      <link>https://dev.to/moukie_6e50335af6c9733592/stop-explaining-your-stack-to-cursor-in-every-new-chat-use-cursorrules-instead-5l5</link>
      <guid>https://dev.to/moukie_6e50335af6c9733592/stop-explaining-your-stack-to-cursor-in-every-new-chat-use-cursorrules-instead-5l5</guid>
      <description>&lt;p&gt;You know the pattern.&lt;/p&gt;

&lt;p&gt;You open a new Cursor chat. You type "fix this bug". Cursor gives you JavaScript with no types, &lt;code&gt;useEffect&lt;/code&gt; where a Server Component would work, and imports from &lt;code&gt;next/router&lt;/code&gt; instead of &lt;code&gt;next/navigation&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So you write: &lt;em&gt;"actually use TypeScript strict mode, we're on App Router, and use next/navigation not next/router"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;It fixes it. Next session: same explanation.&lt;/p&gt;

&lt;p&gt;There's a better way.&lt;/p&gt;




&lt;h2&gt;
  
  
  .cursor/rules/ — persistent context for every chat
&lt;/h2&gt;

&lt;p&gt;Cursor reads every &lt;code&gt;.md&lt;/code&gt; file in your &lt;code&gt;.cursor/rules/&lt;/code&gt; folder at the start of each chat. It's like a system prompt, but per-project, and you write it once.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; .cursor/rules
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now create &lt;code&gt;.cursor/rules/nextjs.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Next.js 14 App Router — Rules&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Server Components by default. Only add "use client" for interactivity or hooks.
&lt;span class="p"&gt;-&lt;/span&gt; Named exports everywhere except page.tsx and layout.tsx.
&lt;span class="p"&gt;-&lt;/span&gt; Use next/navigation (not next/router): useRouter, usePathname, redirect(), notFound().
&lt;span class="p"&gt;-&lt;/span&gt; TypeScript strict mode. No &lt;span class="sb"&gt;`any`&lt;/span&gt;. Use &lt;span class="sb"&gt;`unknown`&lt;/span&gt; and narrow.
&lt;span class="p"&gt;-&lt;/span&gt; Fetch in Server Components when possible — no useEffect + fetch for data.
&lt;span class="p"&gt;-&lt;/span&gt; Tailwind: mobile-first, use cn() for conditional classes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open a new chat. Ask Cursor to "add a server action to fetch the current user". It'll do it correctly — typed, using auth() server-side, no client component — without you explaining anything.&lt;/p&gt;




&lt;h2&gt;
  
  
  Add more rules per concern
&lt;/h2&gt;

&lt;p&gt;Keep each file focused on one topic:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;.cursor/rules/stripe.md&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Stripe — Rules&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Read raw body with req.text() before signature verification — never parse as JSON first.
&lt;span class="p"&gt;-&lt;/span&gt; Verify: stripe.webhooks.constructEvent(body, signature, STRIPE_WEBHOOK_SECRET).
&lt;span class="p"&gt;-&lt;/span&gt; Handle webhooks idempotently — they can fire multiple times.
&lt;span class="p"&gt;-&lt;/span&gt; Attach userId in metadata on checkout session AND subscription_data.metadata.
&lt;span class="p"&gt;-&lt;/span&gt; Never trust amount from client — verify via webhook.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;.cursor/rules/validation.md&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Zod Validation — Rules&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Validate all external input at API boundaries.
&lt;span class="p"&gt;-&lt;/span&gt; Use z.safeParse() when input may be invalid.
&lt;span class="p"&gt;-&lt;/span&gt; Infer TypeScript types: type User = z.infer&lt;span class="nt"&gt;&amp;lt;typeof&lt;/span&gt; &lt;span class="na"&gt;UserSchema&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Validate env vars at startup — crash early if misconfigured.
&lt;span class="p"&gt;-&lt;/span&gt; Never use z.any().
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;code&gt;.cursor/rules/security.md&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Security — Rules&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Verify auth server-side on every protected route — never trust client state.
&lt;span class="p"&gt;-&lt;/span&gt; Check ownership on resource operations: if (post.authorId !== userId) throw Forbidden.
&lt;span class="p"&gt;-&lt;/span&gt; Use parameterized queries — never string concatenation.
&lt;span class="p"&gt;-&lt;/span&gt; Rate limit: 10 req/min per IP on auth endpoints.
&lt;span class="p"&gt;-&lt;/span&gt; Security headers: X-Content-Type-Options, X-Frame-Options, CSP.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Rules vs CLAUDE.md
&lt;/h2&gt;

&lt;p&gt;If you use &lt;strong&gt;Claude Code&lt;/strong&gt; alongside Cursor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.cursor/rules/&lt;/code&gt; → Cursor reads these&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CLAUDE.md&lt;/code&gt; → Claude Code reads this&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They serve similar purposes but different tools. Keep them in sync.&lt;/p&gt;




&lt;h2&gt;
  
  
  What to put in rules
&lt;/h2&gt;

&lt;p&gt;Good rules are &lt;strong&gt;actionable and specific&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;✅ "Use &lt;code&gt;z.safeParse()&lt;/code&gt; when input may be invalid"&lt;br&gt;
✅ "Server Components by default — only add &lt;code&gt;'use client'&lt;/code&gt; when needed"&lt;br&gt;
✅ "Validate env vars at startup with Zod — crash early"&lt;/p&gt;

&lt;p&gt;Bad rules are vague:&lt;/p&gt;

&lt;p&gt;❌ "Write clean code"&lt;br&gt;
❌ "Follow best practices"&lt;br&gt;
❌ "Be careful with security"&lt;/p&gt;

&lt;p&gt;The test: could Cursor misinterpret this? If yes, make it more specific.&lt;/p&gt;




&lt;h2&gt;
  
  
  My full set of rules
&lt;/h2&gt;

&lt;p&gt;I use 25 rule files across my projects — one per topic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js 14 App Router&lt;/li&gt;
&lt;li&gt;React + TanStack Query + Zustand&lt;/li&gt;
&lt;li&gt;Python FastAPI + Pydantic v2&lt;/li&gt;
&lt;li&gt;Go idioms&lt;/li&gt;
&lt;li&gt;Prisma + PostgreSQL (query patterns, indexing)&lt;/li&gt;
&lt;li&gt;Redis caching&lt;/li&gt;
&lt;li&gt;Stripe webhooks&lt;/li&gt;
&lt;li&gt;Auth.js v5&lt;/li&gt;
&lt;li&gt;Tailwind + shadcn/ui&lt;/li&gt;
&lt;li&gt;Anthropic Claude API + OpenAI streaming&lt;/li&gt;
&lt;li&gt;Docker multi-stage builds&lt;/li&gt;
&lt;li&gt;Vercel deployment&lt;/li&gt;
&lt;li&gt;OWASP web security&lt;/li&gt;
&lt;li&gt;Vitest + React Testing Library&lt;/li&gt;
&lt;li&gt;Conventional Commits + Git workflow&lt;/li&gt;
&lt;li&gt;Zod validation&lt;/li&gt;
&lt;li&gt;REST API design&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I packaged them up: &lt;strong&gt;&lt;a href="https://moukieagent.gumroad.com/l/cvmfni" rel="noopener noreferrer"&gt;Cursor Rules &amp;amp; AI Coding Config Pack — $19 on Gumroad&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Includes CLAUDE.md templates for Claude Code users too.&lt;/p&gt;




&lt;p&gt;What rules do you use in your projects? Drop them in the comments.&lt;/p&gt;

</description>
      <category>webdev</category>
    </item>
  </channel>
</rss>
