Different Layers Need Different AI Rules
A full-stack project has two distinct rule domains: the backend (API routes, database queries, authentication, server-side logic) and the frontend (components, state management, styling, client-side interactions). Each layer has: different frameworks (Express/Fastify vs React/Next.js), different concerns (data integrity vs user experience), different testing patterns (integration tests vs component tests), and different security surfaces (SQL injection vs XSS). Writing one generic rule file for both: produces rules that are half-relevant to each layer.
The solution: targeted rules per layer. In a monorepo: packages/api/CLAUDE.md for backend rules and apps/web/CLAUDE.md for frontend rules (using CLAUDE.md hierarchy). In separate repos: each repo gets its own focused CLAUDE.md. In a single-repo fullstack app: use sections in one CLAUDE.md ("# Backend Conventions" and "# Frontend Conventions"). The AI gets: relevant rules for the code it is currently generating.
This article maps: the key rule differences between backend and frontend, what each layer needs that the other does not, the overlap (conventions that apply to both), and how to structure rules for full-stack projects. The goal: the AI generates backend code that is data-safe and API-correct AND frontend code that is component-clean and UX-appropriate — from the same project.
One generic rule file for both layers: backend AI sees React patterns (confusing). Frontend AI sees database patterns (irrelevant). Each layer gets rules that are 50% relevant. With targeted per-layer rules: each layer gets rules that are 100% relevant. The AI generates better code when every rule applies.
Backend-Specific Rules: Data Safety and API Design
Backend rules should cover: input validation ("Validate every API request body with Zod. Never trust client input."), database access ("Use Drizzle ORM. Parameterized queries only. Never raw SQL string concatenation."), authentication ("Verify JWT in middleware. Set X-User-Id header for downstream services."), error handling ("Return structured errors: { error: { code, message, details } }. Never expose stack traces to clients. Log errors with request context."), and API design ("REST with versioning: /api/v1/. Resource-based URLs. HTTP methods for CRUD. Pagination: cursor-based.").
Backend rules that do not apply to frontend: database query patterns (the frontend does not query databases directly), server-side authentication middleware (the frontend sends tokens, the backend validates them), API response format (the backend defines it, the frontend consumes it), rate limiting configuration (server-side concern), and background job patterns (queue processing, cron jobs — backend only). Including these in a frontend rule file: wastes tokens on irrelevant rules.
Backend security rules are: the most critical category. "Parameterized queries only" prevents SQL injection. "Validate all inputs with Zod" prevents malformed data. "Never expose internal errors to clients" prevents information leakage. "Rate limit all public endpoints" prevents abuse. These security rules are: mandatory (see the strict-vs-flexible article) and backend-specific. The frontend has its own security surface (XSS, CSRF) that requires different rules.
- Input validation: Zod on every request body — backend specific, frontend validates forms differently
- Database: Drizzle ORM, parameterized queries — backend only, frontend never queries DB directly
- Auth: JWT validation in middleware, X-User-Id header — backend validates, frontend sends tokens
- Errors: structured { error: { code, message } } format — backend defines, frontend consumes
- Security: SQL injection, input validation, rate limiting — backend security surface
Backend: SQL injection (parameterized queries), input validation (Zod on request body), rate limiting. Frontend: XSS (JSX escaping), CSRF (SameSite cookies), CSP (nonce scripts). Same project, different threat models, different prevention rules. Each layer needs its own security rules.
Frontend-Specific Rules: Components and User Experience
Frontend rules should cover: component architecture ("Server Components by default. Add use client only for useState, useEffect, or browser APIs. Keep use client boundaries narrow."), state management ("Zustand for global client state. TanStack Query for server state. No useState for data that should be in the URL."), styling ("Tailwind CSS with cn() utility. Responsive: mobile-first with md:/lg: prefixes. Dark mode: dark: variant."), form handling ("React Hook Form with zodResolver for 4+ field forms. useState for simple 1-3 field forms."), and accessibility ("Visible labels on all inputs. aria-describedby for error messages. 44px minimum touch targets.").
Frontend rules that do not apply to backend: component patterns (the backend does not render components), state management (Zustand, TanStack Query are frontend libraries), styling conventions (Tailwind, CSS Modules — irrelevant to the API), responsive design (breakpoints, mobile-first — UI concern only), and animation patterns (Framer Motion, CSS transitions — UI only). Including these in a backend rule file: confuses the AI when generating API code.
Frontend security rules differ from backend: XSS prevention ("Never insert raw HTML into the DOM. React JSX escapes by default — only use raw HTML rendering for trusted content."), CSRF protection ("Fetch includes credentials: 'include' for cross-origin authenticated requests. SameSite cookies."), and CSP compliance ("No inline event handlers. Use addEventListener in scripts with nonces."). These are: different security threats with different prevention patterns than the backend.
- Components: Server Components default, narrow use client boundaries — frontend only
- State: Zustand for client, TanStack Query for server, no useState for URL data — frontend only
- Styling: Tailwind, responsive mobile-first, dark: variant — irrelevant to backend
- Accessibility: labels, aria, touch targets, focus management — UI-specific requirements
- Security: XSS prevention, CSRF, CSP compliance — different threats than backend
Structuring Full-Stack Monorepo Rules
The recommended structure: root/CLAUDE.md contains: project description ("Full-stack SaaS app: Next.js web + Express API + shared packages"), shared TypeScript rules, shared naming conventions, shared testing framework (Vitest), shared Git workflow, and shared security principles. This file is: inherited by every subdirectory. Length: 200-400 words.
apps/web/CLAUDE.md contains: Next.js App Router patterns, React Server Components conventions, Tailwind styling, TanStack Query for data fetching, form handling patterns, accessibility requirements, and frontend testing specifics (React Testing Library, MSW for API mocking). This file is: inherited by everything under apps/web/. Length: 200-400 words. apps/web/ AI context: root rules + web rules = 400-800 words of focused, relevant guidance.
packages/api/CLAUDE.md contains: Express routing patterns, Drizzle ORM conventions, Zod input validation, API response format, authentication middleware, error handling for API responses, and backend testing specifics (supertest for HTTP tests, database test fixtures). This file is: inherited by everything under packages/api/. Length: 200-400 words. packages/api/ AI context: root rules + api rules = 400-800 words of focused, relevant guidance. Each layer: maximum relevance, minimum noise.
- root/CLAUDE.md: 200-400 words — TypeScript, naming, testing, Git (shared by all layers)
- apps/web/CLAUDE.md: 200-400 words — React, Tailwind, state, a11y (frontend specific)
- packages/api/CLAUDE.md: 200-400 words — Express, Drizzle, Zod, API format (backend specific)
- Per-layer context: root + layer = 400-800 words of 100% relevant rules
- Maximum guidance, minimum noise: each layer sees only the rules that apply to it
Comparison Summary
Summary of backend vs frontend AI rules.
- Backend: input validation (Zod), database (Drizzle ORM), auth (JWT middleware), API design (REST, versioning)
- Frontend: components (RSC default), state (Zustand, TanStack Query), styling (Tailwind), a11y (labels, ARIA)
- Backend security: SQL injection, input validation, rate limiting. Frontend security: XSS, CSRF, CSP
- Shared: TypeScript strict, naming conventions, testing (Vitest), Git workflow, error philosophy
- Monorepo hierarchy: root (shared) + apps/web (frontend) + packages/api (backend)
- Per-layer context: 400-800 words of 100% relevant rules — no irrelevant rules from other layers
- Single-repo: sections in one CLAUDE.md (# Backend, # Frontend, # Shared at top)
- Targeted rules > generic rules: the AI generates better code when every rule is relevant