Cursor rules for Node.js Express applications with TypeScript, middleware patterns, and error handling.
.cursorrules in your project rootYou are an expert Node.js developer specializing in Express APIs.
## Project Structure
```
src/
├── config/
│ └── index.ts # Configuration
├── controllers/
│ └── userController.ts
├── middleware/
│ ├── auth.ts
│ ├── errorHandler.ts
│ └── validate.ts
├── models/
│ └── User.ts
├── routes/
│ ├── index.ts
│ └── userRoutes.ts
├── services/
│ └── userService.ts
├── utils/
│ └── logger.ts
├── types/
│ └── index.ts
└── app.ts
```
## Express App Setup
```typescript
// app.ts
import express, { Express } from 'express';
import cors from 'cors';
import helmet from 'helmet';
import compression from 'compression';
import { errorHandler } from './middleware/errorHandler';
import { requestLogger } from './middleware/requestLogger';
import routes from './routes';
export function createApp(): Express {
const app = express();
// Security middleware
app.use(helmet());
app.use(cors({
origin: process.env.CORS_ORIGIN,
credentials: true,
}));
// Body parsing
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));
// Compression
app.use(compression());
// Logging
app.use(requestLogger);
// Routes
app.use('/api', routes);
// Health check
app.get('/health', (req, res) => res.json({ status: 'ok' }));
// Error handling (must be last)
app.use(errorHandler);
return app;
}
```
## Controller Pattern
```typescript
// controllers/userController.ts
import { Request, Response, NextFunction } from 'express';
import { UserService } from '../services/userService';
import { CreateUserDto } from '../types';
export class UserController {
constructor(private userService: UserService) {}
getUsers = async (req: Request, res: Response, next: NextFunction) => {
try {
const { page = 1, limit = 10 } = req.query;
const users = await this.userService.findAll({
page: Number(page),
limit: Number(limit),
});
res.json(users);
} catch (error) {
next(error);
}
};
createUser = async (req: Request, res: Response, next: NextFunction) => {
try {
const dto: CreateUserDto = req.body;
const user = await this.userService.create(dto);
res.status(201).json(user);
} catch (error) {
next(error);
}
};
getUser = async (req: Request, res: Response, next: NextFunction) => {
try {
const user = await this.userService.findById(req.params.id);
if (!user) {
res.status(404).json({ error: 'User not found' });
return;
}
res.json(user);
} catch (error) {
next(error);
}
};
}
```
## Error Handling
```typescript
// middleware/errorHandler.ts
import { Request, Response, NextFunction } from 'express';
import { logger } from '../utils/logger';
export class AppError extends Error {
constructor(
public statusCode: number,
public message: string,
public isOperational = true
) {
super(message);
Object.setPrototypeOf(this, AppError.prototype);
}
}
export function errorHandler(
err: Error,
req: Request,
res: Response,
next: NextFunction
) {
if (err instanceof AppError) {
return res.status(err.statusCode).json({
error: err.message,
});
}
// Log unexpected errors
logger.error('Unexpected error:', err);
// Don't leak error details in production
res.status(500).json({
error: process.env.NODE_ENV === 'production'
? 'Internal server error'
: err.message,
});
}
```
## Validation Middleware
```typescript
// middleware/validate.ts
import { Request, Response, NextFunction } from 'express';
import { z, ZodSchema } from 'zod';
export function validate(schema: ZodSchema) {
return (req: Request, res: Response, next: NextFunction) => {
try {
schema.parse({
body: req.body,
query: req.query,
params: req.params,
});
next();
} catch (error) {
if (error instanceof z.ZodError) {
res.status(400).json({
error: 'Validation failed',
details: error.errors,
});
return;
}
next(error);
}
};
}
// Usage
const createUserSchema = z.object({
body: z.object({
email: z.string().email(),
name: z.string().min(1),
password: z.string().min(8),
}),
});
router.post('/users', validate(createUserSchema), userController.createUser);
```Comprehensive Cursor rules for Next.js 14+ with App Router, including routing, layouts, and API patterns.
Cursor rules for TypeScript with strict type checking, advanced patterns, and best practices.
Cursor rules for Tailwind CSS development with responsive design, custom components, and dark mode.
Cursor
backend
AI coding rules customize how Cursor generates and refactors code for your project. Follow these steps to install Node.js Express API Development.
.cursor/rules, for Windsurf use .windsurfrulesComprehensive Cursor rules for Next.js 14+ with App Router, including routing, layouts, and API patterns.
Cursor rules for TypeScript with strict type checking, advanced patterns, and best practices.
Cursor rules for Tailwind CSS development with responsive design, custom components, and dark mode.