Complete AI prompt library for MERN stack developers. Production-ready prompts for MongoDB schema design, Express REST APIs, React components, authentication, testing, CI/CD, and performance — with good vs bad prompt examples and architecture guidance.
Why MERN Developers Using AI Prompts Ship Faster
The MERN stack powers millions of production applications in 2026. The engineers building fastest on this stack aren't writing less — they're prompting better. A vague request like "build me a login" produces generic, insecure boilerplate that needs hours of rework. A precisely engineered AI prompt produces a JWT rotation system with Redis session management, OWASP-compliant security headers, Zod validation, and full test coverage — ready to review and ship.
Every prompt in this guide follows the CRISP framework: assign a senior role, set the context, define exact requirements, specify the output format, and state the security constraints. These are the prompts senior MERN engineers use in real production workflows — not tutorial examples.
Picking the Right AI Model for MERN Stack Work
Not every model handles MERN the same way. Here is how each performs on the tasks MERN developers actually do daily.
| Model | Best For (MERN) | Weak Spot | When to Reach For It |
|---|---|---|---|
| Claude Sonnet | Architecture review, TypeScript refactoring, multi-file analysis | Occasionally verbose on simple one-liners | Reviewing 500-line Express middleware, planning multi-tenant schema, explaining complex aggregation pipelines |
| ChatGPT GPT-5.5 | Greenfield React component generation, CRUD route scaffolding | Forgets project conventions in long sessions | Generating components from Figma descriptions, writing API routes from an OpenAPI spec |
| Gemini 3.5 Flash | Library comparisons, security advisories, current npm ecosystem research | Complex multi-file code generation | Researching MongoDB Atlas Search vs Elasticsearch, comparing Zustand vs Jotai, checking current CVEs |
| Cursor | In-editor autocomplete with real codebase context | Hallucinating imports from your project that don't exist | Active coding sessions — it reads your actual files and respects your patterns |
| GitHub Copilot | Repetitive boilerplate, test case scaffolding after it sees your pattern | Still suggests CommonJS in ESM projects; outdated Mongoose v6 patterns | Writing the 10th similar CRUD route after it has learned your controller style |
| Grok | Direct trade-off analysis, second opinions on architecture decisions | Less depth on MERN-specific library APIs | Comparing Redis vs MongoDB for session storage without getting a diplomatic non-answer |
| DeepSeek | Alternative implementations, bulk scaffolding at low cost | Less reliable on security-critical auth flows | Generating seed data factories, writing JSDoc comments, scaffolding repetitive utility functions |
Day-to-day, Cursor handles the typing. Claude handles the thinking. ChatGPT handles greenfield generation when you have a clean spec. The mistake most MERN teams make is using one tool for everything — context window management alone makes the case for switching between models by task type.
One specific note: for Mongoose aggregation pipelines, Claude outperforms every other model in the list. Paste your schema and your target query pattern, ask for the full aggregate() with index recommendations and memory estimates, and you will get something a DBA would recognize as competent. ChatGPT and Copilot often produce pipelines that work but miss the stage ordering that prevents COLLSCAN.
1. Architecture & Project Structure
Architecture decisions made on day one are the most expensive to undo. Use this prompt before writing the first line of application code.
You are a senior MERN stack architect who has built and scaled SaaS products to 1M+ users.
Design a production-grade monorepo structure for a multi-tenant MERN SaaS with:
- Express 5 + TypeScript API with REST and WebSocket support
- React 19 + Vite frontend, Zustand for global state
- MongoDB + Mongoose 8, multi-tenant with soft deletes and audit logging
- Redis for sessions, rate limiting, and Bull job queues
- Role-based access control: super_admin, org_admin, manager, member
Deliver:
1. Full directory tree (client/, server/, shared/ packages)
2. Module boundary decisions with one-sentence reasoning for each
3. Shared TypeScript types strategy (where they live, how they are imported)
4. .env.example with every required variable and a comment for each
5. The top 3 architectural trade-offs you considered and why you chose this pattern over the alternatives
Why it works: Asking for trade-offs forces the AI to justify choices rather than dump a tutorial structure. You get reasoning you can defend in a team architecture review.
2. MongoDB Schema Design with Indexing Strategy
Schema design determines query performance at scale. Get it right before you have 10 million documents to migrate.
You are a MongoDB expert who has designed schemas for applications with 50M+ documents and 10K+ requests per second.
Design Mongoose 8 TypeScript schemas for a project management app: Organization, User, Project, Task, Comment.
Requirements:
- Tenant isolation: tenantId indexed on every document
- Soft deletes: isDeleted (boolean) + deletedAt (Date) on all entities
- Audit trail: createdBy, updatedBy (ObjectId refs), createdAt, updatedAt (timestamps)
- Justify every reference vs embed decision with the query pattern that drove it
- Compound indexes for these access patterns:
* All tasks for a project sorted by dueDate (most frequent query)
* Overdue tasks for an organization filtered by assignee
* Full-text search on task title and description
* User activity feed (tasks created or updated in last 7 days)
- Virtuals: User.fullName, Task.isOverdue, Task.completionPercentage
Output: TypeScript Mongoose schemas, index definitions using index() chaining, and a two-sentence justification for each reference vs embed decision.
Why it works: Specifying exact access patterns forces index design around your real query load — not textbook examples. The justification requirement surfaces reasoning that would otherwise require a senior DBA review.
3. MongoDB Aggregation Pipeline
You are a MongoDB aggregation expert.
Write a Mongoose aggregate() pipeline for a real-time dashboard that computes for a given organizationId:
- Task completion rate per user for the last 30 days (top 10 by completion count)
- Average task completion time in hours per project
- Overdue task count grouped by priority (low / medium / high / critical)
- Week-over-week completion trend for the last 8 weeks (ISO week grouping)
Collection: tasks
Key fields: status (todo/in_progress/done/cancelled), assignedTo (ObjectId), completedAt (Date),
createdAt (Date), dueDate (Date), priority (String), projectId (ObjectId), organizationId (ObjectId)
Provide:
1. The complete aggregate() call with TypeScript result types using generics
2. A comment above each pipeline stage explaining what it does and why
3. Which indexes this pipeline requires to avoid COLLSCAN
4. Estimated memory usage if the pipeline processes 500,000 matching documents
4. Express REST API Controller
Without explicit constraints, AI produces middleware-light routes that fail under production load or fail a security audit.
You are a senior Express.js engineer building production APIs for high-scale SaaS products.
Generate a complete TypeScript Express 5 controller for a Task resource:
Endpoints: GET /tasks (paginated, filterable), GET /tasks/:id, POST /tasks, PUT /tasks/:id, DELETE /tasks/:id (soft delete)
Every endpoint must include:
- Zod validation schemas (request body, query params, route params)
- authenticate middleware: verify JWT, attach req.user with role and tenantId
- authorize middleware factory: requirePermission('tasks:write')
- Tenant-scoped queries: always filter by req.user.tenantId
- Optimistic concurrency on PUT: check version field, return 409 on conflict
- Structured responses: { success, data?, pagination?, message, code? }
- Async error propagation to global error handler (express-async-errors)
- Request ID propagation: read x-request-id header, attach to all log lines
- Response time logging: warn if endpoint exceeds 200ms
Output: router file, controller, Zod schemas, middleware references. TypeScript throughout.
5. Production Express Middleware Stack
You are a Node.js security engineer.
Build a production-grade Express 5 middleware stack in TypeScript. Implement in this exact order with explanation for why order matters:
1. Helmet: strict CSP, HSTS max-age=31536000, X-Frame-Options DENY
2. CORS: allowlist from CORS_ORIGINS env var (comma-separated), credentials: true
3. Rate limiting: 100 req/min per IP, Redis-backed (ioredis), return 429 with Retry-After header
4. Request ID: generate UUID v4, attach to req.id and set X-Request-ID response header
5. Structured logging: pino with JSON format, include request ID, method, path, status, duration
6. Body parser: JSON with 10kb size limit, reject oversized bodies with 413
7. Compression: gzip/brotli based on Accept-Encoding, threshold 1KB
8. JWT authentication: attach to specific route groups (not global), skip /health and /auth/login
9. Global error handler: log with request ID, return structured JSON, never leak stack trace in production
Output: app.ts setup file with all middleware. Add a comment on each line explaining the security or performance reason for its position in the stack.
Why it works: The "explain why order matters" constraint documents your security reasoning inline — the kind of documentation that normally only appears after an incident post-mortem.
6. JWT Authentication with Refresh Token Rotation
You are a security engineer specializing in stateless authentication for Node.js APIs.
Implement a complete JWT auth system for Express 5:
Access tokens:
- RS256 (asymmetric — private key signs, public key verifies; keys loaded from env)
- 15-minute expiry
- Payload: { sub: userId, role, tenantId, iat, exp }
Refresh tokens:
- Stored in Redis with key: refresh:{userId}:{tokenFamily}
- 7-day expiry, delivered via httpOnly + Secure + SameSite=Strict cookie
- Token family tracking: each refresh generates new family ID
- Reuse detection: if a used token is presented again, invalidate the entire family, log a security event
Endpoints:
- POST /auth/login: bcrypt compare (timing-safe), issue both tokens
- POST /auth/refresh: validate Redis entry, rotate token, issue new pair
- POST /auth/logout: delete Redis entry, clear cookie
- Rate limit: 5 auth attempts per 15 minutes per IP
Output: TypeScript auth router, JWT utilities, Redis token service, and auth middleware. Add a security comment explaining each design decision.
Why it works: Token family tracking and reuse detection prevent refresh token theft attacks that most auth implementations miss. Baking them into the prompt ensures you get them from the start, not after a breach.
7. Role-Based Access Control (RBAC) Middleware
You are an authorization systems architect.
Build a dynamic RBAC middleware system for Express with:
- Roles: super_admin, org_admin, manager, member, viewer
- Permission matrix: tasks:read, tasks:write, tasks:delete, projects:manage, org:manage, billing:manage
- Permission inheritance: super_admin inherits all; org_admin inherits manager's permissions; viewer is read-only
- Multi-tenant scoping: a user can be org_admin in Organization A but member in Organization B
- Middleware factory: requirePermission('tasks:write') — returns Express middleware
- Permission check utility: hasPermission(user, resource, action, tenantId): boolean
- Redis caching for permission lookups: TTL 5 minutes, auto-invalidate on role change
- Audit logging: log every permission denial with user ID, resource, action, tenantId, timestamp
TypeScript. Output: permission matrix object, middleware factory, Redis cache layer, and 5 usage examples showing different permission scenarios.
8. React Data Table with Virtual Scrolling
You are a senior React engineer specializing in performant, accessible UI components.
Build a DataTable<T extends Record<string, unknown>> React component with TypeScript generics for a MERN admin panel:
Required features:
- Virtual scrolling for 50,000+ rows using @tanstack/react-virtual
- Multi-column sorting with direction indicators (client-side and server-side modes via prop)
- Row selection: checkbox per row, shift+click range, select-all on current page
- Column resizing via drag handle
- Per-column filters (text, date range, enum select based on column type)
- Pagination: client-side and server-side modes
- Row action menu via renderRowActions prop (receives row data, returns ReactNode)
- States: loading skeleton (animated), empty state, error state with retry button
- WCAG 2.1 AA: keyboard navigation (arrow keys, Enter to select), ARIA grid role, screen reader announcements on sort/select
TypeScript interfaces required for: ColumnDef<T>, SortState, FilterState, PaginationState, SelectionState.
CSS Modules for styling. Zero external UI library dependencies.
9. Custom React Hook: useFetch with Cache
You are a React hooks architect.
Build a production-ready useFetch<T> hook:
interface UseFetchOptions {
deduplicate?: boolean; // prevent concurrent identical requests (default: true)
ttl?: number; // cache TTL in ms (default: 30000)
retries?: number; // automatic retry count (default: 3)
retryDelay?: number; // base delay for exponential backoff in ms (default: 1000)
onError?: (err: Error) => void;
}
Requirements:
- Request deduplication: same URL + body = single in-flight request (Map-based)
- SWR-style in-memory cache with TTL and stale-while-revalidate behaviour
- AbortController cancellation on component unmount or URL change
- Exponential backoff retry: 1s, 2s, 4s with jitter
- States: { data, loading, error, stale, refetch, mutate }
- mutate(): optimistic update + background revalidation on POST/PUT/DELETE
- TypeScript strict mode: no any types
Include: hook implementation, TypeScript types, and 4 usage examples (GET with pagination, POST with optimistic update, polling with interval, conditional fetch).
10. Zustand State Architecture
You are a React state management expert.
Design a Zustand store architecture for a MERN project management app. Create these stores:
authStore: user object, access token (in memory, never localStorage), auto-refresh logic (intercept 401, call /auth/refresh, retry original request), logout (clear all stores)
projectStore: CRUD operations, optimistic updates with rollback on failure, real-time sync via Socket.io events
taskStore: paginated task lists, active filters, sort state, bulk operations (assign, update status, delete)
uiStore: modal registry (open/close by ID), toast queue (max 5 visible), sidebar collapsed state, theme (light/dark)
Requirements:
- Persist authStore and uiStore to sessionStorage (not localStorage for auth tokens)
- Immer middleware for immutable state updates
- Redux DevTools middleware in development
- Selector hooks to prevent unnecessary re-renders: useTasksByProject(projectId)
- Action naming: verb + noun (fetchTasks, updateTask, clearFilters)
Output: full TypeScript store files, middleware configuration, and 3 selector hook examples.
11. Unit Tests with 100% Branch Coverage
You are a test engineering expert for Node.js MERN applications.
Write comprehensive Jest unit tests for this Express service function:
[PASTE SERVICE FUNCTION CODE HERE]
Cover every branch:
- Happy path for each operation
- Zod validation failures (missing fields, wrong types, business rule violations)
- Unauthorized access (missing JWT, expired JWT, wrong role)
- Tenant boundary violations (accessing another tenant's data)
- MongoDB errors: validation error, duplicate key (11000), connection timeout
- Redis errors: cache miss (handled gracefully), Redis connection failure (graceful degradation)
- Rate limit exceeded
Requirements:
- Mock all external dependencies: Mongoose models, ioredis, nodemailer, external APIs
- jest.spyOn for side effects: email sends, audit log writes, Socket.io emissions
- Assert on response shape, HTTP status code, and response headers
- AAA pattern: Arrange, Act, Assert with labeled comments
- Factory functions for test data (no hardcoded magic values)
- Target: 100% branch coverage — show coverage report format in a top comment
12. GitHub Actions CI/CD Pipeline
You are a DevOps engineer building CI/CD pipelines for MERN production applications.
Generate a complete GitHub Actions workflow for a MERN monorepo:
lint-and-test job (triggers on all PRs and main push):
- Node 22, pnpm with cache
- TypeScript compile check: tsc --noEmit on both client and server
- ESLint + Prettier check (fail on warnings)
- Server: Jest unit + integration tests, coverage gate 80%, upload to Codecov
- Client: Vitest unit tests + Playwright E2E against local server (docker-compose up)
security job (parallel to lint-and-test):
- npm audit --audit-level=high (fail build on high+ vulnerabilities)
- Trivy container scan on Dockerfile
- CodeQL analysis for JavaScript/TypeScript
docker job (main branch only, after lint-and-test passes):
- Multi-stage build: builder (tsc compile) + production (node:22-alpine, non-root user)
- Push to AWS ECR: tag with git SHA and 'latest'
- Image size check: fail if production image exceeds 200MB
deploy job (after docker job):
- Backend: AWS ECS rolling update via AWS CLI (zero-downtime)
- Frontend: Vercel CLI deploy
- Smoke test: curl /api/health, assert HTTP 200 and { status: 'ok' }
- Slack notification on success or failure with deploy URL
Include secrets management pattern and required GitHub repository secrets list.
13. MongoDB Query Performance Optimization
You are a MongoDB performance engineer who has optimized queries on collections with 100M+ documents.
This aggregation pipeline runs in 4,200ms on a collection with 8M documents. Here is the current pipeline and indexes:
[PASTE PIPELINE + INDEXES HERE]
Diagnose and fix:
1. Run an EXPLAIN — identify whether it is COLLSCAN or IXSCAN and why
2. Recommend the optimal compound index (specify field order and direction with reasoning)
3. Rewrite any pipeline stages that block before the $match (push $match as early as possible)
4. Identify stages that can use $lookup with pipeline to filter before joining
5. Assess whether this result should be pre-computed in a separate summary collection (materialized view pattern)
6. Estimate query time after optimization
Context: 70% read workload, this query runs 80,000 times per day during business hours.
14. Docker Multi-Stage Build for Node.js API
You are a DevOps engineer building production Docker images for Node.js APIs.
Write an optimized multi-stage Dockerfile for an Express 5 + TypeScript API:
Stage 1 (deps): install production + dev dependencies
Stage 2 (build): run tsc, output to dist/
Stage 3 (production):
- Base: node:22-alpine (not full Debian)
- Copy: dist/, node_modules (production only, re-installed from package.json)
- Non-root user: create 'appuser' (UID 1001), chown app directory, USER appuser
- EXPOSE the port from PORT env variable
- Health check: GET /health every 30s, 3 retries, 10s start period
- CMD: ["node", "dist/server.js"]
- No secrets, no .env files, no source code in final stage
After the Dockerfile:
1. A .dockerignore file
2. A docker-compose.yml for local development with MongoDB, Redis, and the API (volume mounts for hot-reload, depends_on with healthcheck conditions)
3. Three sentences explaining why multi-stage + non-root matters for production security
15. Socket.io Real-Time Collaboration
Without explicit room scoping, AI generates examples that broadcast to all connected clients — a data leak in any multi-tenant app.
You are a Node.js real-time systems engineer.
Add Socket.io v4 to an existing Express 5 + TypeScript MERN app for collaborative task editing:
Authentication: verify JWT on connection using socket.use() middleware — reject unauthenticated connections with socket.disconnect()
Room strategy: one room per projectId (join on 'join-project' event, leave on disconnect)
Events to implement:
- task:updated — broadcast to room when any user updates a task (include updatedBy and timestamp)
- task:locked — optimistic lock when user starts editing (payload: taskId, lockedBy, expiresAt)
- task:unlocked — release lock on save or 30s timeout
- user:typing — debounced typing indicator (suppress if same user, broadcast to others in room)
- connection:error — typed error events with code and message
Deliver:
1. Socket.io server setup integrated with existing Express app (shared HTTP server)
2. Auth middleware with JWT verify and req.user attachment
3. All event handlers with TypeScript event map types
4. React hook: useProjectSocket(projectId) — manages connect/disconnect lifecycle, exposes event emitters and listeners
5. Redis adapter setup (socket.io-redis) for horizontal scaling
Pro tip: The 30-second lock expiry on task:locked is critical — without it, a user who closes the tab holds the lock forever. Follow up with "add a heartbeat that resets the lock TTL every 10 seconds while the user is actively editing."
16. Stripe Payment Integration
You are a senior Node.js payments engineer with Stripe expertise.
Implement a Stripe subscription integration for an Express 5 TypeScript MERN SaaS:
Plans: starter ($29/mo), pro ($99/mo), enterprise (contact sales)
Implement:
1. POST /billing/create-checkout-session — Stripe Checkout with success_url and cancel_url, metadata: { userId, planId }
2. POST /billing/webhook — verify Stripe-Signature header (stripe.webhooks.constructEvent), handle: checkout.session.completed, customer.subscription.updated, customer.subscription.deleted, invoice.payment_failed
3. MongoDB subscription schema: customerId, subscriptionId, status, planId, currentPeriodEnd, cancelAtPeriodEnd
4. Middleware: requireActiveSubscription — check subscription.status === 'active' and currentPeriodEnd > now()
5. Webhook idempotency: store processed event IDs in Redis (TTL 24h), skip duplicates
Security requirements:
- Never log Stripe webhook raw body after signature verification
- Store only customerId and subscriptionId in MongoDB, not payment method details
- Webhook endpoint must be excluded from CSRF middleware
Output: router, webhook handler, MongoDB schema, and billing middleware. TypeScript throughout.
17. File Upload to AWS S3
You are a Node.js backend engineer specializing in file handling and cloud storage.
Build a production-grade file upload system for a MERN app:
Stack: multer (memory storage, never disk), @aws-sdk/client-s3 v3, sharp for image processing
Requirements:
- POST /uploads: accept multipart/form-data, max 10MB, allowed MIME types: image/jpeg, image/png, image/webp, application/pdf
- Validation: check Content-Type header AND magic bytes (first 4 bytes) — not just file extension
- Images: resize to max 1920px width with sharp, preserve aspect ratio, strip EXIF metadata (privacy)
- Generate S3 key: uploads/{tenantId}/{year}/{month}/{uuid}.{ext} — never use user-supplied filenames
- S3 upload: Server-Side Encryption (SSE-S3), private ACL (no public URLs), signed URLs for access (1-hour expiry)
- MongoDB: store only the S3 key + metadata (size, mimeType, uploadedBy, tenantId) — not the signed URL
- Rate limit: 20 uploads per user per hour
- Cleanup: if MongoDB save fails after S3 upload, delete the S3 object (compensating transaction)
Output: upload router, S3 service, image processor, and FileUpload Mongoose schema. TypeScript.
18. Email Queue with Bull + Nodemailer
You are a Node.js infrastructure engineer.
Build a production email queue system for an Express TypeScript MERN app:
Queue: BullMQ (not legacy Bull) with Redis, queue name: 'email'
Job types: welcome, password-reset, task-assigned, weekly-digest, invoice
For each job type:
- TypeScript interface for job data (no loose objects)
- Rate limit: 100 emails/hour per tenant, 10 password-reset per hour per email (anti-spam)
- Retry strategy: 3 attempts, exponential backoff (30s, 2min, 10min), dead-letter queue after 3 failures
- Priority: password-reset = high (1), welcome = normal (5), weekly-digest = low (10)
Worker:
- Nodemailer with SMTP transport (credentials from env), TLS required
- HTML templates with Handlebars (no inline styles — use inlined CSS via juice)
- Track sends in MongoDB: EmailLog { jobId, recipient, type, status, sentAt, error? }
- Concurrency: 5 workers, graceful shutdown (drain queue before process exit)
Output: queue setup, worker, email service interface, and example usage for each job type.
19. Full-Text Search with MongoDB Atlas Search
You are a search systems engineer.
Implement full-text search for a MERN task management app using MongoDB Atlas Search:
Index definition (Atlas Search, not legacy text indexes):
- Collection: tasks
- Fields: title (analyzed), description (analyzed), tags (keyword), assignedTo.name (analyzed)
- Custom analyzer: lowercase, stop words removed, edge n-gram for prefix matching
Search endpoint: GET /tasks/search?q=&filters=&page=&limit=
- Autocomplete: match title as user types (edge n-gram, debounced 300ms on client)
- Filters: status, priority, assignedTo (ObjectId), dueDate range — combine with compound query
- Relevance scoring: boost title matches over description, boost recently updated documents
- Pagination: cursor-based (not skip/limit — inconsistent on live data), return searchAfter cursor
- Tenant scoping: pre-filter by tenantId using filter clause (not must — preserves score)
Output: Atlas Search index definition JSON, Mongoose aggregate pipeline for search, React useSearch hook with debounce, and the compound query structure for combined search + filters.
20. Refactor: JavaScript to TypeScript Migration
I have an existing Express 5 JavaScript file that I need to convert to strict TypeScript. Here is the file:
[PASTE FILE HERE]
Requirements:
- TypeScript strict mode (strict: true in tsconfig — no exceptions)
- No 'any' types — infer or define explicit interfaces for everything
- Define interfaces for: request body shapes, query parameter shapes, response objects, database documents
- For Mongoose models: use the generic Model<IDocument> pattern with discriminator keys where applicable
- Preserve all existing behavior exactly — do not fix bugs or add features
- Add JSDoc comments only where the type alone doesn't convey intent (e.g. non-obvious business rules)
- After the converted file, list every type you created and whether it should live in a shared types package
Output: the converted TypeScript file, followed by a list of any assumptions you made about types that I should verify.
Pro tip: After the AI converts it, run tsc --noEmit and paste the errors back in a follow-up: "Fix these TypeScript compiler errors without changing behavior: [errors]"
21. Debug: Memory Leak in Express
You are a Node.js performance engineer specializing in memory leak diagnosis.
My Express 5 Node.js API (running on Node 22) shows steadily increasing heap usage under load — memory climbs from 150MB to 800MB over 6 hours then OOMs. I have attached:
1. Heap snapshot 1 (taken at startup after warmup): [DESCRIBE OR PASTE SUMMARY]
2. Heap snapshot 2 (taken 4 hours in): [DESCRIBE OR PASTE SUMMARY]
3. The most-called route handler: [PASTE ROUTE CODE]
4. My middleware stack order: [LIST MIDDLEWARE]
Diagnose:
1. What memory category is growing? (strings, arrays, closures, event listeners, Buffers)
2. What is the most likely root cause given the code? List your top 3 suspects in order.
3. For each suspect: what specific heap snapshot comparison evidence would confirm it?
4. Write a targeted fix for the most likely cause
5. What process.memoryUsage() logging should I add to confirm the fix worked in production?
22. OpenAPI/Swagger Documentation
You are a technical documentation engineer.
Generate a complete OpenAPI 3.1.0 specification for this Express 5 TypeScript router:
[PASTE ROUTER FILE HERE]
Requirements:
- Extract every route, HTTP method, path parameter, query parameter, and request body
- Generate response schemas from the Zod validation schemas in the file (or infer from code)
- Authentication: Bearer token (JWT) using securitySchemes, mark every protected route
- Include: 200 success response, 400 validation error (with Zod error shape), 401 unauthorized, 403 forbidden, 404 not found, 429 rate limited, 500 server error
- Examples: include at least one request/response example per endpoint
- Servers: development (http://localhost:3001), production (https://api.{your-domain}.com)
- Tags: group endpoints by resource name
Output: complete OpenAPI 3.1.0 YAML. After the YAML, list any assumptions you made about undocumented behavior.
23. Observability with OpenTelemetry
You are a platform engineer specializing in Node.js observability.
Add OpenTelemetry distributed tracing to an Express 5 TypeScript API:
SDK: @opentelemetry/sdk-node, @opentelemetry/auto-instrumentations-node
Exporter: OTLP/HTTP to a Grafana Tempo endpoint (URL from env OTEL_EXPORTER_OTLP_ENDPOINT)
Instrument:
- All HTTP requests: method, route (not raw path — use route pattern to avoid cardinality explosion), status, duration
- All Mongoose operations: collection name, operation type, duration — exclude query text (contains PII risk)
- All Redis operations: command name, duration, key prefix (not full key)
- Custom spans: wrap any function over 50ms with a named span
- Error recording: attach exception to span on any caught Error, set span status to ERROR
Custom attributes on every span:
- tenant.id, user.id (from authenticated request context — use AsyncLocalStorage to propagate)
- deployment.environment (from NODE_ENV)
- service.version (from package.json version)
Output: tracer setup file, instrumentation bootstrap (loaded before any other imports), middleware that attaches trace ID to response as X-Trace-ID header, and example of wrapping a Mongoose service method with a custom span.
24. React Performance Audit
You are a React performance engineer.
Audit this React component for performance issues and fix them:
[PASTE COMPONENT CODE HERE]
Check and fix each of these categories:
1. Unnecessary re-renders: identify which state/prop changes cause the component to re-render when they shouldn't — add React.memo, useMemo, useCallback where warranted (with justification for each, not blindly)
2. useEffect dependencies: find any missing or over-specified dependencies — fix the array, don't add eslint-disable comments
3. Expensive computations in render: identify calculations that should be memoized
4. Stale closures: find any event handlers or callbacks that capture stale state
5. Large list rendering: if this renders more than 50 items, recommend windowing (@tanstack/react-virtual)
6. Bundle impact: identify any imports that should be lazy-loaded or code-split
For each issue: show the problematic code, explain why it is a problem, and show the fixed version.
25. Test Fixtures & Seed Data Factory
You are a test infrastructure engineer.
Build a type-safe test data factory system for a MERN TypeScript project:
Requirements:
- Factory pattern: createUser(overrides?), createOrganization(overrides?), createProject(overrides?), createTask(overrides?)
- Each factory: generates valid MongoDB ObjectIds, realistic fake data (faker-js), satisfies all Mongoose schema validators
- Override merging: deep merge, so createTask({ status: 'done', assignedTo: userId }) only overrides those fields
- Relationship factories: createProjectWithTasks(taskCount, overrides?) — creates project + N tasks with correct references
- Seed script: seeds a local MongoDB with 5 organizations, 20 users per org, 10 projects per org, 50 tasks per project — runnable with 'pnpm seed'
- Reset helper: clearDatabase() — drops all collections, usable in beforeEach for integration tests
- TypeScript: factory return types match the Mongoose document interfaces exactly — no casting
Output: factory file, seed script, and 3 example usages in Jest integration test context.
End-to-End Workflow: Spec to Deployed Feature
Here is how a senior MERN engineer would chain these prompts to ship a complete feature — in this case, adding a task comment system with real-time updates and email notifications.
- Schema design (Prompt 2 variant): Design the Comment Mongoose schema with tenantId, taskId, authorId, content (sanitized HTML), reactions array, editHistory array, soft delete. Get the compound indexes for "all comments on task X sorted by createdAt" and "recent comment activity by user."
- API routes (Prompt 4 variant): Generate the Comment REST controller — GET /tasks/:taskId/comments, POST, PUT, DELETE — with Zod validation, RBAC (only comment author can edit/delete), tenant scoping, and optimistic concurrency on edits.
- Real-time (Prompt 15 variant): Add Socket.io events: comment:created, comment:updated, comment:deleted — scoped to the task's project room. Include the React hook useTaskComments(taskId).
- Notifications (Prompt 18 variant): Add a BullMQ job that fires when a comment is created: notify all task participants except the commenter. Rate-limit to one digest per user per 30 minutes if multiple comments land quickly.
- Tests (Prompt 11 variant): Write Jest + Supertest integration tests for the comment API: paste the controller code, ask for coverage of all branches including permission failures and concurrent edit conflicts.
- Review: After AI generates each piece, run
tsc --noEmit, run tests, then review with: "Review this code for: missing tenant isolation, any async operations without error handling, and any user-supplied data that reaches MongoDB without sanitization."
The total prompt-to-reviewed-code time for this feature: roughly 45 minutes instead of a full day. The time savings come from the review prompts as much as the generation prompts — catching missing tenant scoping before it ships is where AI pays off most.
Where AI Goes Wrong in MERN Stack
AI makes specific, predictable mistakes in MERN codebases. Know them before they reach production.
- Missing tenant scoping. AI-generated Mongoose queries almost never include the tenantId filter unless you explicitly require it. Example:
Task.find({ projectId })instead ofTask.find({ projectId, tenantId: req.user.tenantId }). Fix: add "always scope queries to req.user.tenantId" to every prompt that touches a Mongoose model. - Outdated Mongoose syntax. Models trained before 2024 generate Mongoose v6 patterns: deprecated
.execPopulate(), old-style.lean()placement, missing TypeScript generics on Query. Specify "Mongoose 8 with TypeScript strict mode" explicitly. - React 18 patterns in React 19 projects. AI still suggests
ReactDOM.render(), legacyuseEffectfor data fetching (use Server Components instead), and class-based error boundaries (useuse()with Suspense). Specify "React 19 with App Router patterns" even for client-side components. - Express 4 patterns in Express 5 projects. Express 5 handles async errors natively — no
express-async-errorswrapper needed. AI still imports it. Minor issue, but adds dead dependencies. - Hardcoded secrets in generated .env examples. AI sometimes generates
JWT_SECRET=mysecretkey123in example files. Never commit these. Always replace with a note to use a secrets manager. - Missing AbortController cleanup in React hooks. AI-generated fetch hooks frequently lack AbortController cleanup in the useEffect return function, causing "setState on unmounted component" warnings and memory leaks in development.
Good vs Bad MERN Stack Prompts
| Task | ❌ Bad Prompt (generic output) | ✅ Good Prompt (production output) |
|---|---|---|
| MongoDB schema | "Create a user model in MongoDB" | "Create a Mongoose 8 TypeScript User schema with: bcrypt-hashed password (never returned in queries), email unique + indexed, role enum, tenantId indexed, soft delete fields, OAuth provider linking array, and a compound index on [email, tenantId, isDeleted]." |
| Express route | "Build a login endpoint" | "Build POST /auth/login in Express 5 TypeScript: Zod validation, bcrypt timing-safe compare, RS256 JWT (15min), refresh token in Redis + httpOnly SameSite=Strict cookie (7 days), rate limit 5/15min, return 401 on any failure without revealing whether email or password was wrong." |
| React component | "Build a task form" | "Build a CreateTaskForm with React Hook Form + Zod, TypeScript generics, async multi-select user search with 300ms debounce, optimistic UI during submission, localStorage autosave every 30s, and useBlocker warning before navigating away with unsaved changes." |
| Debugging | "Why is my app slow?" | "My GET /api/tasks returns in 1,800ms. Here is the route code: [CODE]. My current Mongoose indexes: [INDEXES]. MongoDB EXPLAIN output: [EXPLAIN]. Identify the root cause, propose the optimal compound index with field order reasoning, and rewrite the query." |
| Testing | "Write tests for my service" | "Write Jest unit tests for this TaskService.create() function: [CODE]. Mock mongoose, ioredis, and nodemailer. Cover happy path, Zod validation failure, duplicate key error (11000), Redis cache miss, and email notification failure. Target 100% branch coverage." |
Before You Prompt: MERN Stack Context Setup
MERN applications span four different runtimes and library ecosystems. Without an explicit context block, AI mixes library versions, defaults to CommonJS when you use ESM, and generates React class components nobody writes in 2026. Paste this block before every MERN session:
Context for all MERN prompts in this session:
- React 19 + Vite 6 (frontend)
- Express 5 + Node.js 22 LTS (backend)
- Mongoose 8 + MongoDB 8 (database)
- TypeScript 5.4, strict mode, ESM throughout
- Auth: JWT (RS256), access token 15min, refresh token in Redis (7 days)
- State: Zustand 5 + TanStack Query v5
- Testing: Vitest + React Testing Library (frontend), Supertest + mongodb-memory-server (backend)
Never generate:
- CommonJS require() — always ESM import/export
- React class components or lifecycle methods
- var declarations — use const/let
- mongoose.connect() inside route files (only in app startup)
- Synchronous file operations (always async/await)
The testing stack line is especially important — "write tests for this route" with no context produces random Jest or Mocha code that doesn't match your project. Specifying Supertest + mongodb-memory-server tells the AI to spin up an in-memory MongoDB instance for each test suite, giving you real query behavior without a running database.
3 Common Mistakes When Prompting AI for MERN Stack
Mistake 1: Not wrapping async Express route handlers
Asking "write an Express route" without specifying error handling produces async route handlers where unhandled promise rejections silently swallow errors and the request hangs. In Express 5 async errors propagate automatically — but Express 4 still needs explicit try-catch or the express-async-errors package. Specify your Express version and say: "all async errors must propagate to the Express error handler — do not silently catch." This one requirement dramatically changes the generated code.
Mistake 2: Mongoose populate() without field projection
Asking for "populate the user field" generates code that fetches every field of every related document — including password hashes, internal flags, and audit fields. Always specify: "populate user with projection: { name: 1, email: 1, avatar: 1 } — never return the password field." In a list endpoint returning 50 tasks with 50 populated users, the difference between projecting 3 fields vs all fields is 10–50x the data over the wire.
Mistake 3: useEffect for server data fetching in React
AI still generates useEffect(() => fetch('/api/data').then(...)) patterns because they dominate pre-2023 training data. This approach loses caching, background refresh, deduplication, and loading/error state management. Specify: "use TanStack Query v5 with useQuery — never useEffect for data fetching from the API." The resulting component is shorter, has better loading states, and handles race conditions correctly.
Further Reading
Resources for deeper MERN stack AI development:
- How engineering teams use AI to ship faster — AI integration strategies for full-stack JavaScript teams: from architecture decisions to automated code review
- How to write the perfect AI prompt — the CRISP framework that underpins every prompt in this guide
- AI Coding Prompt Library — 50+ copy-ready prompts for MongoDB, Express, React, Node.js, debugging, and performance optimization
Generate a custom MERN stack prompt for your exact use case → Try PromptPrepare free
Help & Answers
Frequently Asked Questions
Found this helpful?
Save it to your library or share with your team.
Keep Reading