Cursor can generate rich documentation with UML-like class diagrams, relationship descriptions, and architectural notes embedded in docstrings when given explicit documentation rules. By adding documentation standards to .cursorrules and prompting Cursor to include class relationships, method flows, and dependency descriptions, you get self-documenting code that serves as both reference and architectural guide.
Getting better documentation from Cursor
Most Cursor-generated code includes minimal or no documentation. By configuring documentation rules and using specific prompts, you can make Cursor produce detailed docstrings that include class relationships, method call flows, and Mermaid-compatible diagrams. This creates self-documenting code that helps new team members understand architecture without separate documentation.
Prerequisites
- Cursor installed with a project containing complex classes
- Understanding of JSDoc or Python docstring formats
- Familiarity with Cursor Chat (Cmd+L) and Cmd+K
- Optional: Mermaid diagram renderer for previewing diagrams
Step-by-step guide
Add documentation rules to .cursor/rules
Add documentation rules to .cursor/rules
Create rules that define your documentation standards. These rules tell Cursor what to include in every docstring it generates, from simple function descriptions to architectural context.
1---2description: Documentation standards3globs: "src/**/*.ts"4alwaysApply: true5---67## Documentation Rules8- Every class must have a docstring with:9 - One-line summary10 - @description with purpose and architectural role11 - @relationships listing dependent and dependency classes12 - @example with basic usage13- Every public method must have:14 - @param for each parameter with type and purpose15 - @returns with type and description16 - @throws for each possible error17- For complex classes, include a Mermaid classDiagram in the docstring18- Use @see to reference related classes and modulesExpected result: Cursor generates detailed documentation following your standards for every class and method.
Generate a documented class with Cursor
Generate a documented class with Cursor
Ask Cursor to generate a class with full documentation including relationships and a Mermaid diagram. Reference your rules and any related classes for accurate relationship mapping.
1// Cursor Chat prompt (Cmd+L):2// @src/services/OrderService.ts @src/repositories/OrderRepository.ts3// @.cursor/rules/documentation.mdc4// Generate a PaymentService class that processes payments for orders.5// Include full JSDoc with Mermaid class diagram showing relationships6// to OrderService, PaymentGateway, and NotificationService.78/**9 * PaymentService — processes payments for customer orders.10 *11 * @description Handles payment processing, refunds, and payment12 * status tracking. Coordinates between the order service and13 * external payment gateway.14 *15 * @relationships16 * - Depends on: OrderService (order lookup), PaymentGateway (processing)17 * - Depended on by: OrderController, WebhookHandler18 * - Notifies: NotificationService (payment events)19 *20 * ```mermaid21 * classDiagram22 * OrderController --> PaymentService23 * PaymentService --> OrderService24 * PaymentService --> PaymentGateway25 * PaymentService --> NotificationService26 * class PaymentService {27 * +processPayment(orderId, amount)28 * +refundPayment(paymentId)29 * +getPaymentStatus(paymentId)30 * }31 * ```32 */Pro tip: Mermaid diagrams in JSDoc comments render in VS Code with the Mermaid extension and in GitHub markdown previews.
Expected result: A fully documented class with relationship diagram, method descriptions, and architectural context.
Add documentation to existing classes with Cmd+K
Add documentation to existing classes with Cmd+K
Select an undocumented class, press Cmd+K, and ask Cursor to add comprehensive documentation. Reference related files so Cursor can accurately describe relationships.
1// Select the class declaration, press Cmd+K:2// @src/services/OrderService.ts @src/repositories/UserRepository.ts3// Add comprehensive JSDoc documentation to this class.4// Include: summary, description with architectural role,5// relationships (depends on, depended on by), Mermaid class6// diagram, and @example usage. Document all public methods7// with @param, @returns, and @throws.Expected result: Existing class receives complete documentation without modifying the implementation.
Generate a module-level architecture document
Generate a module-level architecture document
Use Cursor Chat to generate an overview document for an entire module. This creates a README-style docstring at the top of an index file that maps the entire module structure.
1// Cursor Chat prompt (Cmd+L):2// @src/services/ Generate a module-level JSDoc comment for3// src/services/index.ts that documents:4// - All services in this directory and their purposes5// - The dependency graph between services6// - A Mermaid flowchart showing the service layer architecture7// - Which services are entry points vs internal89/**10 * @module services11 *12 * Service layer handling business logic.13 *14 * ```mermaid15 * flowchart TD16 * OrderController --> OrderService17 * OrderService --> PaymentService18 * OrderService --> InventoryService19 * PaymentService --> NotificationService20 * InventoryService --> NotificationService21 * ```22 *23 * Entry points: OrderService, UserService, AuthService24 * Internal: NotificationService, InventoryService25 */Expected result: A module-level documentation block with architecture diagram and service inventory.
Keep documentation updated as code changes
Keep documentation updated as code changes
After modifying a class, ask Cursor to update the documentation to reflect the changes. This prevents documentation drift, which is the most common reason teams abandon docstrings.
1// After adding a new method to PaymentService, press Cmd+K:2// "Update the JSDoc for this class to include the new3// refundPartial() method. Update the Mermaid diagram4// if any new relationships were added. Keep all existing5// documentation intact."Expected result: Documentation updated to reflect new methods and relationships without losing existing content.
Complete working example
1/**2 * PaymentService — processes payments and manages refunds.3 *4 * @description Coordinates between order management, external payment5 * gateways, and notification delivery. Handles the full payment6 * lifecycle: authorization, capture, and refund.7 *8 * @relationships9 * - Depends on: IOrderService, IPaymentGateway, INotificationService10 * - Depended on by: OrderController, WebhookHandler, AdminPanel11 *12 * ```mermaid13 * classDiagram14 * class PaymentService {15 * -orderService: IOrderService16 * -gateway: IPaymentGateway17 * -notifications: INotificationService18 * +processPayment(orderId, amount) Promise~Payment~19 * +refundPayment(paymentId) Promise~Refund~20 * +getStatus(paymentId) Promise~PaymentStatus~21 * }22 * PaymentService --> IOrderService23 * PaymentService --> IPaymentGateway24 * PaymentService --> INotificationService25 * ```26 *27 * @example28 * const payment = await paymentService.processPayment('order-123', 99.99);29 * console.log(payment.status); // 'captured'30 */3132import type { IOrderService } from '@/types/interfaces';33import type { IPaymentGateway, INotificationService } from '@/types/interfaces';3435export class PaymentService {36 constructor(37 private readonly orderService: IOrderService,38 private readonly gateway: IPaymentGateway,39 private readonly notifications: INotificationService40 ) {}4142 /**43 * Process a payment for an order.44 * @param orderId - The order to charge45 * @param amount - Payment amount in dollars46 * @returns The created payment record47 * @throws {Error} If order not found or gateway rejects48 */49 async processPayment(orderId: string, amount: number) {50 const order = await this.orderService.getOrder(orderId);51 const payment = await this.gateway.charge(amount, order.currency);52 await this.notifications.send(order.userId, 'payment_success');53 return payment;54 }5556 /**57 * Refund a previous payment.58 * @param paymentId - The payment to refund59 * @returns The refund record60 * @throws {Error} If payment not found or already refunded61 */62 async refundPayment(paymentId: string) {63 return this.gateway.refund(paymentId);64 }65}Common mistakes when getting better documentation from Cursor
Why it's a problem: Generating documentation that does not match the actual code
How to avoid: Always select the actual class code and use Cmd+K to add documentation. Never generate documentation in a separate Chat session without referencing the file.
Why it's a problem: Including implementation details in architectural documentation
How to avoid: Add to .cursorrules: 'Docstrings describe WHAT and WHY, not HOW. Implementation details belong in inline comments.'
Why it's a problem: Creating overly verbose documentation on simple functions
How to avoid: Add a rule: 'Full documentation for classes and complex methods only. Simple utility functions need only a one-line @description.'
Best practices
- Add documentation rules to .cursor/rules so Cursor generates docs consistently
- Include Mermaid diagrams for classes with 3+ relationships
- Use @see references to link related classes in docstrings
- Update documentation with Cmd+K after every significant code change
- Focus documentation on WHAT and WHY, not implementation details
- Use @example blocks with realistic usage patterns
- Keep module-level documentation in index.ts barrel files
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
Create a PaymentService class in TypeScript with comprehensive JSDoc documentation. Include: one-line summary, description with architectural role, @relationships section listing dependencies and dependents, Mermaid classDiagram showing the class and its connections, @example usage, and all public methods documented with @param, @returns, and @throws.
In Cursor (Cmd+K, with class selected): @src/services/ @src/types/interfaces.ts Add comprehensive JSDoc to this class. Include summary, architectural description, @relationships, Mermaid classDiagram showing all connections, @example, and document all public methods with @param @returns @throws.
Frequently asked questions
Will Mermaid diagrams in JSDoc render anywhere?
Mermaid diagrams render in GitHub markdown, GitLab, Notion, and VS Code with the Mermaid extension. In JSDoc comments, they serve as readable ASCII documentation even without rendering.
Should I document every function?
Document all public/exported functions and classes. Private helper functions with clear names rarely need full JSDoc. Add a threshold rule to .cursorrules.
Can Cursor generate Swagger/OpenAPI documentation?
Yes. Ask Cursor to add decorators like @ApiProperty (NestJS) or generate OpenAPI YAML from your route handlers. Reference your API types for accurate schemas.
How do I prevent documentation from going stale?
Update docs with every code change using Cmd+K. Add a .cursor/rules directive: 'When modifying a function, update its JSDoc to reflect the changes.' Consider adding a CI lint check for JSDoc coverage.
Is there a maximum useful documentation length?
Class docstrings should be under 30 lines including the diagram. Method docstrings should be under 10 lines. Beyond that, documentation becomes noise rather than signal.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation