How to generate full CRUD features with Cursor. How to prompt Cursor for complete CRUD operations in one session. How to reference your schema for accurate model generation. Configure .cursorrules and use @file context in Cursor Chat (Cmd+L) or Composer (Cmd+I) for best results.
Generating Complete CRUD Features with Context
Cursor generates higher quality CRUD code when it can see your database schema, existing service patterns, and API conventions. Instead of generating each operation separately, this tutorial shows you how to prompt Composer to generate the complete vertical slice: model, repository, service, routes, validation, and tests in a single workflow.
Prerequisites
- Cursor installed (Pro recommended for Agent mode)
- A backend project with an existing CRUD example to reference
- Database schema or migration files
- A REST or GraphQL API framework configured
Step-by-step guide
Reference your schema and existing CRUD as templates
Reference your schema and existing CRUD as templates
Open Composer (Cmd+I) and reference your database schema plus one existing well-structured CRUD module. Cursor will replicate the patterns from the existing module for the new entity.
1// Prompt to type in Cursor Composer (Cmd+I):2// @docs/schema.sql @src/modules/users/ @src/types/user.ts3// Generate a complete CRUD module for Products following4// the exact same patterns as the users module.5// Include:6// 1. Product type/interface7// 2. Product repository (database queries)8// 3. Product service (business logic)9// 4. Product routes (REST API endpoints)10// 5. Product validation (zod schemas)11// 6. Product tests (unit + integration)12// Follow the same file structure as src/modules/users/.Pro tip: The strongest pattern for CRUD generation is referencing an existing module. Cursor copies the structure, imports, error handling, and patterns exactly.
Expected result: A complete CRUD module with 6+ files following your existing conventions.
Define entity-specific business rules
Define entity-specific business rules
After the initial scaffold, use Chat (Cmd+L) to add entity-specific business logic. Reference the generated service file and specify validation rules, computed fields, and side effects unique to this entity.
1// Prompt to type in Cursor Chat (Cmd+L):2// @src/modules/products/productService.ts3// Add these business rules to the product service:4// - SKU must be unique (check before create/update)5// - Price must be positive integer (cents)6// - Slug auto-generated from name7// - Soft delete (set deletedAt instead of removing)8// - Cache product by ID in Redis for 5 minutes9// Keep the same service pattern, just add the rules.Expected result: The service is updated with entity-specific business rules while maintaining the CRUD pattern.
Generate validation schemas
Generate validation schemas
Use Cmd+K to generate zod validation schemas from your TypeScript types. Select the type definition and ask Cursor to create a matching validation schema with appropriate constraints.
1// Select the Product interface, press Cmd+K:2// Generate zod validation schemas for this type:3// - createProductSchema: all required fields4// - updateProductSchema: all optional (partial update)5// - productQuerySchema: pagination + filter params6// Add: string length limits, positive number checks,7// enum validation for status/category fields.Expected result: Complete zod validation schemas matching your TypeScript types with appropriate constraints.
Generate API route tests
Generate API route tests
Use Composer to generate integration tests for all CRUD endpoints. Reference the routes file and your test setup so Cursor generates tests using your testing patterns.
1// Prompt to type in Cursor Composer (Cmd+I):2// @src/modules/products/productRoutes.ts @src/test/setup.ts3// Generate integration tests for all product CRUD endpoints:4// - POST /products: create with valid data, validation error, duplicate SKU5// - GET /products: list with pagination, filtering6// - GET /products/:id: found, not found7// - PUT /products/:id: update, validation error, not found8// - DELETE /products/:id: soft delete, not found9// Follow test patterns from the setup file.Pro tip: Test generation for CRUD is often the highest-value use of Cursor because it covers repetitive cases that developers tend to skip.
Expected result: Complete integration tests for all CRUD endpoints covering happy paths and error cases.
Complete working example
1import { Router, Request, Response, NextFunction } from 'express';2import { ProductService } from './productService';3import { createProductSchema, updateProductSchema, productQuerySchema } from './productValidation';4import { NotFoundError, ValidationError } from '@/shared/errors';56const router = Router();7const service = new ProductService();89router.post('/', async (req: Request, res: Response, next: NextFunction) => {10 try {11 const data = createProductSchema.parse(req.body);12 const product = await service.create(data);13 res.status(201).json(product);14 } catch (error) {15 next(error);16 }17});1819router.get('/', async (req: Request, res: Response, next: NextFunction) => {20 try {21 const query = productQuerySchema.parse(req.query);22 const result = await service.list(query);23 res.json(result);24 } catch (error) {25 next(error);26 }27});2829router.get('/:id', async (req: Request, res: Response, next: NextFunction) => {30 try {31 const product = await service.getById(req.params.id);32 if (!product) throw new NotFoundError('Product not found');33 res.json(product);34 } catch (error) {35 next(error);36 }37});3839router.put('/:id', async (req: Request, res: Response, next: NextFunction) => {40 try {41 const data = updateProductSchema.parse(req.body);42 const product = await service.update(req.params.id, data);43 if (!product) throw new NotFoundError('Product not found');44 res.json(product);45 } catch (error) {46 next(error);47 }48});4950router.delete('/:id', async (req: Request, res: Response, next: NextFunction) => {51 try {52 const deleted = await service.softDelete(req.params.id);53 if (!deleted) throw new NotFoundError('Product not found');54 res.status(204).send();55 } catch (error) {56 next(error);57 }58});5960export { router as productRoutes };Common mistakes when generating Full CRUD Features with Cursor
Why it's a problem: Generating each CRUD operation in a separate session
How to avoid: Generate the entire CRUD module in a single Composer session by referencing an existing module as a template.
Why it's a problem: Not including validation in CRUD generation
How to avoid: Always include 'Generate zod validation schemas for create and update operations' in your CRUD prompt.
Why it's a problem: Forgetting error handling in route handlers
How to avoid: Add a .cursorrules entry: 'All route handlers must be wrapped in try/catch with next(error) for Express error middleware.'
Best practices
- Reference an existing CRUD module as a template for consistent patterns
- Generate the complete vertical slice in a single Composer session
- Include validation schemas, error handling, and tests in the generation prompt
- Add entity-specific business rules in a follow-up prompt after initial scaffold
- Use @docs/schema.sql to ensure generated code matches your actual database
- Test soft delete and pagination in generated test suites
- Commit each generated module to Git as a clean baseline before customizing
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
Generate a complete CRUD module for a Product entity in Express/TypeScript. Include: router with 5 endpoints, service with business logic, repository with PostgreSQL queries, zod validation, error handling, and integration tests.
@docs/schema.sql @src/modules/users/ Generate a complete CRUD module for Products following the users module patterns. Include: types, repository, service, routes (POST/GET/PUT/DELETE), zod validation, and tests. Same file structure and error handling as users.
Frequently asked questions
How can I leverage AI to generate CRUD operations quickly?
Reference an existing CRUD module and your database schema in a single Cursor Composer session. Prompt for the complete vertical slice: types, repository, service, routes, validation, and tests. Cursor generates the entire module in minutes.
Can Cursor generate CRUD for GraphQL instead of REST?
Yes. Reference your GraphQL schema and an existing resolver module. Prompt for: type definitions, resolvers, input validation, and tests. Cursor handles both REST and GraphQL CRUD patterns.
Should I generate CRUD in one session or multiple?
One session for the initial scaffold (all files), then follow-up sessions for entity-specific business rules and edge cases. This keeps the initial generation consistent.
Can Cursor generate CRUD with pagination?
Yes. Specify pagination requirements in your prompt: 'Include cursor-based pagination on the list endpoint with configurable limit.' Reference your schema for the correct ordering column.
How do I add authentication to CRUD endpoints?
Reference your auth middleware with @file and instruct Cursor: 'Apply authMiddleware to all routes. Require admin role for create, update, delete. Allow authenticated users for read operations.'
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation