Why Generic Rules Are Not Enough for Frameworks
Generic rules ('use async/await,' 'handle errors properly') apply to any JavaScript project. But a Next.js App Router project has specific patterns that generic rules miss: Server Components vs Client Components (the default is Server, add 'use client' only when needed), Server Actions (how to define and call server functions from client code), File-based routing (page.tsx, layout.tsx, loading.tsx, error.tsx — each has a specific purpose), and Data fetching (no useEffect for data — fetch in Server Components or use Server Actions).
Without framework rules: the AI generates a React component with useEffect for data fetching (valid React, wrong for Next.js App Router). With framework rules: the AI generates a Server Component with direct async data fetching (idiomatic Next.js). The difference: working code vs idiomatic code. Both compile. Only one follows the framework's intended patterns. AI rule: 'Framework rules transform AI output from technically correct to idiomatically correct. The framework's patterns exist for performance, security, and maintainability reasons.'
The extraction technique: read the framework's official documentation (the 'Getting Started' and 'Best Practices' sections). For each recommendation: write an AI rule that encodes it. The result: a ruleset that makes the AI generate code the framework's maintainers would approve.
The Rule Extraction Process (30 Minutes per Framework)
Step 1 — File structure rules (5 min): how does the framework organize files? Next.js: app/ directory with page.tsx, layout.tsx, loading.tsx per route. NestJS: modules containing controllers, services, and DTOs. FastAPI: routers, schemas, and dependencies. AI rule: 'List the framework's file conventions: what files go where, what each file type does, and what naming convention each follows. The AI uses this to create new files in the correct location with the correct name.'
Step 2 — Component/module pattern rules (10 min): how does the framework structure its units of code? Next.js: Server Components (default), Client Components (interactive), Server Actions (mutations). NestJS: Controllers (HTTP handling), Services (business logic), Modules (dependency grouping). FastAPI: route functions with type-hinted parameters, Pydantic models for request/response. AI rule: 'For each framework pattern: describe when to use it, what it contains, and what it does not contain. Example: NestJS Services contain business logic. They do not contain HTTP-specific code (no Request/Response objects).'
Step 3 — Data flow rules (10 min): how does data move through the framework? Next.js: props from Server to Client Components, Server Actions for mutations, route handlers for API endpoints. NestJS: Request → Controller → Service → Repository → Database. FastAPI: Request → route function → dependency injection → response model. AI rule: 'The data flow rules prevent the AI from: putting database calls in Next.js Client Components, putting HTTP handling in NestJS Services, or returning unvalidated data in FastAPI responses.'
The framework's official documentation: already describes every pattern, convention, and best practice. You do not need to invent rules — you extract them. Read the 'Getting Started' guide: 5 rules about file structure and project setup. Read the 'Best Practices' section: 5 rules about patterns and anti-patterns. Read the 'API Reference' for key components: 5 rules about correct usage. Total: 15 rules in 30 minutes. Each one: backed by the framework maintainers' recommendations.
Example: Next.js App Router Ruleset
File structure: 'App Router: src/app/ directory. Each route: a folder with page.tsx (the page component), layout.tsx (shared layout, optional), loading.tsx (loading UI, optional), and error.tsx (error boundary, optional). API routes: src/app/api/{route}/route.ts with exported GET, POST, PUT, DELETE functions.' Component model: 'Default: Server Components (no directive needed, run on the server, can be async, can directly access the database). Client Components: add "use client" directive only when needed (event handlers, useState, useEffect, browser APIs). Minimize Client Components — they add to the client JavaScript bundle.'
Data fetching: 'Server Components: fetch data directly (async function Page() { const data = await db.query... }). No useEffect for data fetching — that is a Client Component pattern from Pages Router. Server Actions: for mutations (form submissions, data updates). Define with "use server" directive. Call from Client Components via form action or direct invocation.' State management: 'URL search params for shareable state. Server Components for server-derived state. Client state (useState): only for UI-specific state that does not need to be server-aware or shareable.'
Styling: 'Tailwind CSS with design tokens from tailwind.config. Use cn() utility for conditional classes. Component library: check src/components/ui/ before creating new components. Dark mode: use dark: variants on all color classes.' Performance: 'Images: next/image component (automatic optimization). Fonts: next/font (automatic optimization). Metadata: export metadata object from page.tsx for SEO.' AI rule: 'A complete Next.js App Router ruleset: 15-20 rules covering file structure, components, data flow, styling, and performance. The AI generates idiomatic Next.js code that follows the framework's intended architecture.'
The AI knows React. React uses useEffect for data fetching. So the AI generates: useEffect(() => { fetch('/api/users').then(...) }, []). In a Pages Router project: this is fine. In an App Router project: this is wrong. Server Components can fetch data directly (const users = await db.query...). The useEffect: adds unnecessary client-side JavaScript, creates a loading waterfall, and misses the Server Component performance benefit. Framework rules: prevent the AI from applying one framework's patterns to another.
Adapting for Other Frameworks
NestJS ruleset focus: modules (every feature is a module with controller + service + DTOs), dependency injection (use constructor injection, register providers in the module), decorators (@Controller, @Injectable, @Get, @Post — the AI must generate with the correct decorators), and pipes (validation pipes on all endpoints, transform DTOs with class-validator). AI rule: 'NestJS rules emphasize: the module pattern (not free-floating controllers), DI over manual instantiation, and decorator-based routing.'
FastAPI ruleset focus: type hints (all function parameters and return types annotated), Pydantic models (for request body validation and response serialization), dependency injection (Depends() for shared logic — authentication, database sessions, rate limiting), and async (async def for route handlers, await for all I/O operations). AI rule: 'FastAPI rules emphasize: type safety (Pydantic + type hints), DI via Depends(), and async-first handlers.'
The adaptation technique: for any framework, ask 3 questions. (1) How are files organized? (file structure rules). (2) How are code units structured? (pattern rules). (3) How does data flow? (data flow rules). The answers: become the framework-specific rules. Spend 30 minutes with the framework's documentation: produce 15-20 rules that make the AI generate idiomatic code. AI rule: 'Any framework can be encoded in 15-20 rules. The rules are extracted from the framework's documentation, not invented. If the framework recommends it: it becomes a rule.'
(1) How are files organized? → file structure rules. (2) How are code units structured? → pattern rules. (3) How does data flow? → data flow rules. These three questions work for every framework: Next.js, NestJS, FastAPI, Django, Rails, Spring Boot, SvelteKit, Remix, Astro, Flutter. The answers differ per framework. The questions are universal. Spend 10 minutes per question. The result: a complete framework ruleset.
Framework Ruleset Summary
Summary of creating framework-specific AI rulesets.
- Why: generic rules produce generic code. Framework rules produce idiomatic code
- Extraction: read the framework's docs. Each recommendation = one AI rule. 30 min per framework
- Step 1: file structure rules (where files go, what they are named, what each contains)
- Step 2: component/module pattern rules (when to use each pattern, what it contains and does not)
- Step 3: data flow rules (how data moves through the framework, what each layer handles)
- Next.js: Server Components default, no useEffect for data, Server Actions for mutations, Tailwind
- NestJS: module pattern, DI via constructor, decorators for routing, validation pipes
- FastAPI: Pydantic models, Depends() DI, async handlers, type hints on everything