AI
50 AI Prompts for Express.js and Node.js API Development
A practical collection of 50 prompts for building production-grade REST APIs with Express.js and Node.js. Covers project setup, routing, middleware, database integration, authentication, error handling, testing, and deployment.
How to Use These Express.js Prompts
Express.js remains the most widely used Node.js web framework. Its minimal, unopinionated design means you make most architectural decisions yourself — which folder structure to use, how to handle errors, where to put middleware, and how to structure routes. That freedom is powerful but means a lot of boilerplate decisions that AI can handle for you.
These 50 prompts cover the full Express.js API development lifecycle. They are written for Express 4 with Node.js 20, and work with any capable AI assistant including Claude, ChatGPT, and GitHub Copilot Chat. Always paste in your existing files before running a prompt that modifies them — the AI produces far better output when it can see your current patterns.
- Add your current folder structure and naming conventions before running setup prompts
- For prompts about middleware or error handling, paste your existing app.js or server.js
- Specify whether you are using CommonJS or ESM modules at the top of each session
- Break complex prompts into steps: route first, then controller, then service layer
Project Setup and Architecture (Prompts 1-8)
Prompt 1: Create a production-ready Express.js project structure using ESM modules and Node.js 20. Show the full folder layout with src/routes, src/controllers, src/services, src/middleware, src/models, and src/config. Include a server.js entry point, a dotenv configuration loader, a graceful shutdown handler for SIGTERM and SIGINT, and a health check route at GET /health that returns the Node.js version and uptime.
Prompt 2: Write a src/config/index.js that loads and validates all environment variables on startup using the envalid library. Define required variables for PORT, NODE_ENV, DATABASE_URL, and JWT_SECRET with descriptive error messages if any are missing or invalid. Export a frozen config object. Prompt 3: Create an Express.js app.js that registers global middleware in the correct order: helmet for security headers, cors with configurable allowed origins, express.json with a 10MB body limit, express-rate-limit for API throttling (100 requests per 15 minutes), a request ID middleware that generates and attaches a UUID to each request, and a request logger using morgan.
- Prompt 4: Write a graceful shutdown handler for an Express.js server that waits for active connections to close before exiting, sets a 10-second timeout as a fallback, closes the database connection pool, logs the shutdown reason, and exits with code 0 on clean shutdown or code 1 on timeout.
- Prompt 5: Create a router factory in src/routes/index.js that registers all route modules, prefixes API routes with /api/v1, adds a catch-all 404 handler after all routes, and exports the configured Express router. Show how to add a new route module without modifying this file.
- Prompt 6: Write an Express.js middleware that validates API version from the URL path, rejects requests to deprecated versions with a 410 Gone response, and sets a Deprecation header on versions scheduled for removal.
- Prompt 7: Create a request validation middleware using the Zod library. It should validate req.body, req.query, and req.params against schemas passed as arguments, return structured 400 errors with field-level messages, and strip unknown properties from the request before passing it to the controller.
- Prompt 8: Write an Express.js response helper module that standardises all API responses. Include sendSuccess(res, data, statusCode), sendError(res, message, statusCode, details), sendPaginated(res, items, page, limit, total), and sendCreated(res, data, location) helpers. Every response should include a success boolean, a timestamp, and a requestId.
Routes, Controllers, and Services (Prompts 9-20)
Prompt 9: Write a full CRUD route module for a products resource in Express.js. Include GET /products with pagination (page, limit, sort, search), GET /products/:id, POST /products, PUT /products/:id, PATCH /products/:id, and DELETE /products/:id. Each route should call a corresponding controller method. Add express-validator rules for the create and update body schemas.
Prompt 10: Create a controller-service pattern for the products resource. The ProductsController handles HTTP concerns only: reading from req, calling ProductsService, and sending responses. ProductsService contains all business logic: validation, data transformation, and database calls. Show dependency injection by passing the service to the controller constructor. Prompt 11: Write a ProductsService with these methods: findAll with cursor-based pagination returning items and a nextCursor, findById that throws a NotFoundError for unknown IDs, create that validates uniqueness before inserting, update that returns the updated document, and softDelete that sets a deletedAt timestamp instead of removing the record.
- Prompt 12: Create an asyncHandler wrapper for Express.js that catches any error thrown or rejected inside an async route handler and passes it to next(err) automatically, eliminating try-catch blocks from every controller method.
- Prompt 13: Write Express.js route-level caching middleware using node-cache. The middleware should cache GET responses by URL and query string for a configurable TTL, add Cache-Status: HIT or MISS headers, skip caching when the Authorization header is present, and provide a clearCache(pattern) function for invalidation after writes.
- Prompt 14: Create a file upload route in Express.js using multer. Accept up to 5 image files per request (JPEG, PNG, WebP only, max 2MB each), validate MIME type from the file buffer not just the extension, generate unique filenames using UUID, and return the list of saved file paths in the response.
- Prompt 15: Write an Express.js route that handles webhook delivery from Stripe. Read the raw body before JSON parsing, verify the webhook signature using the Stripe SDK, route events to handler functions by event type, acknowledge receipt immediately with 200, and process events asynchronously so slow handlers do not delay the response.
- Prompt 16: Create an Express.js proxy route that forwards requests to an internal microservice, adds an internal API key header, strips sensitive headers from the upstream response before returning it to the client, and logs the proxied URL and response status for debugging.
Database Integration (Prompts 21-30)
Prompt 21: Write a MongoDB connection module for an Express.js app using Mongoose. Configure the connection with a connection pool of 10, a 5-second server selection timeout, retry on disconnect, and a connection event logger. Export a connectDB function called on app startup and a disconnectDB function called during graceful shutdown.
Prompt 22: Create a Mongoose User model with email (unique, lowercase, trimmed), passwordHash (not selected by default), role (enum: user, admin, superadmin, default user), isActive (default true), lastLoginAt, createdAt, and updatedAt. Add a pre-save hook that hashes the password if modified, an instance method comparePassword, and a static method findByEmail. Prompt 23: Write a Mongoose repository pattern with a BaseRepository class that provides findAll with filter and sort, findById, create, update, softDelete, and count methods. Show how to extend it for specific models like UserRepository and ProductRepository.
- Prompt 24: Create a PostgreSQL connection module for Express.js using the pg library with a connection pool. Include a query helper function that accepts SQL and parameters, logs slow queries over 200ms, and wraps connection errors in a DatabaseError class with the original query for debugging.
- Prompt 25: Write a database migration system for a Node.js Express app using the migrate library. Show how to create numbered migration files, run pending migrations on startup in production, roll back the last migration in development, and track migration state in a schema_migrations table.
- Prompt 26: Create a Redis cache module for Express.js using ioredis. Implement get, set with TTL, delete, and deleteByPattern methods. Add a cacheAside helper that wraps any async data-fetching function with transparent caching. Handle Redis connection failures gracefully so the API continues working without cache.
- Prompt 27: Write a full-text search endpoint in Express.js using MongoDB Atlas Search. Accept a query string and optional filters, build the aggregation pipeline with the $search stage, return results with a relevance score and highlighted match snippets, and paginate with the searchAfter cursor pattern.
- Prompt 28: Create a database seeding script for an Express.js application that creates admin and test users with bcrypt-hashed passwords, generates 100 sample products with realistic data using faker, runs in a transaction that rolls back all inserts if any fail, and is safe to run multiple times.
Authentication and Security (Prompts 31-38)
Prompt 31: Write a complete JWT authentication system for Express.js. Include a POST /auth/register route that hashes passwords with bcrypt and creates a user, a POST /auth/login route that returns a signed access token (15-minute expiry) and a refresh token (7-day expiry) stored in an HttpOnly cookie, a POST /auth/refresh route that issues a new access token from the cookie refresh token, and a POST /auth/logout route that clears the cookie.
Prompt 32: Create an authenticate middleware for Express.js that reads the JWT from the Authorization: Bearer header, verifies it with jsonwebtoken, attaches the decoded payload to req.user, and calls next(). If the token is missing return 401. If expired return 401 with a specific expired: true flag. If tampered return 403. Prompt 33: Write a role-based access control middleware for Express.js. Define an authorize(...roles) factory that returns middleware checking req.user.role against the allowed roles. Return 403 Forbidden if the role does not match. Show usage on admin-only and moderator routes.
- Prompt 34: Create an API key authentication system in Express.js. Generate API keys as SHA-256 hashed values stored in the database with metadata (name, permissions, lastUsedAt, expiresAt). Write an authenticateApiKey middleware that reads the X-API-Key header, hashes it, looks it up, updates lastUsedAt, and attaches the key owner to req.
- Prompt 35: Write an Express.js middleware that implements CSRF protection for cookie-based sessions using the double-submit cookie pattern. Generate a CSRF token on login, set it in a readable cookie and in the session, validate it against the X-CSRF-Token header on mutating requests, and skip validation for API key authenticated requests.
- Prompt 36: Create a brute-force protection middleware for the POST /auth/login route using express-rate-limit and an in-memory store. Allow 5 failed attempts per IP per 15 minutes, lock the account temporarily after 10 failures across any IP, return a Retry-After header when rate limited, and reset the counter on successful login.
- Prompt 37: Write an input sanitisation middleware for Express.js that recursively sanitises req.body to strip HTML tags and script content using the sanitize-html library, prevents MongoDB operator injection by removing keys starting with $, and logs any sanitised values to a security audit log.
- Prompt 38: Create a security audit logger middleware that records every 401, 403, and 429 response to a security_events collection with the endpoint, IP address, user agent, userId if authenticated, and a reason code. Show how to query these events for detecting coordinated attacks.
Error Handling and Logging (Prompts 39-43)
Prompt 39: Write a complete error handling setup for an Express.js application. Define a hierarchy of custom error classes: AppError (base), NotFoundError (404), ValidationError (400), AuthenticationError (401), ForbiddenError (403), and ConflictError (409). Each should carry a message, statusCode, and optional details object. Write a global error handler middleware that formats all these into consistent JSON responses and logs unexpected errors with their stack traces.
Prompt 40: Create a structured logging setup for Express.js using Pino. Configure different log levels for development (pretty print) and production (JSON). Add a request logger that records method, URL, status code, response time, and request ID on every request. Show how to add contextual fields like userId and sessionId to all log lines within a request using Pino child loggers. Prompt 41: Write an Express.js middleware that catches unhandled promise rejections and uncaughtException events at the process level, logs them with full context, flushes the log buffer, and gracefully shuts down the server rather than crashing immediately.
- Prompt 42: Create a health check endpoint at GET /health that returns the application status, version from package.json, database connectivity status (alive/down), Redis connectivity status, uptime in seconds, and memory usage. Return 200 when healthy and 503 when any dependency is unavailable.
- Prompt 43: Write an Express.js middleware that adds distributed tracing headers to all outbound HTTP requests made during a request lifecycle. Propagate the X-Request-ID and X-Trace-ID headers, generate a new span ID for each outbound call, and log the full trace context when a request completes.
Testing and Deployment (Prompts 44-50)
Prompt 44: Write Jest unit tests for an Express.js controller. Mock the service layer completely using jest.mock, test that the controller returns the correct status codes and response shapes for success cases, test that it calls next(error) when the service throws, and test input validation rejection before the service is called.
Prompt 45: Write a supertest integration test for an Express.js authentication flow. Start the real Express app in the test, use an in-memory MongoDB instance via mongodb-memory-server, test the full register, login, and access-protected-route flow, verify that expired tokens are rejected, and clean up the database between tests. Prompt 46: Create a load test script for an Express.js API using autocannon. Define 5 scenarios: unauthenticated public endpoints, authenticated user endpoints, write-heavy POST endpoints, paginated list endpoints, and a mixed realistic traffic pattern. Show how to analyse the output for p99 latency and error rate targets.
- Prompt 47: Write a multi-stage Dockerfile for an Express.js application. Stage 1 installs all dependencies and runs any build steps. Stage 2 copies only the production node_modules and source into an Alpine Node.js image. Set NODE_ENV to production, run as a non-root user, expose port 3000, and add a HEALTHCHECK that calls GET /health.
- Prompt 48: Write a docker-compose.yml for local Express.js development with live reload using nodemon, a MongoDB 7 service with authentication and a named volume, a Redis 7 service, and a mongo-express admin UI. Use environment variable defaults so the compose file works without a .env file.
- Prompt 49: Create a PM2 ecosystem.config.js for running an Express.js API in production. Use cluster mode with the number of workers set to the CPU count, configure the log file paths, set environment variables for production, add a max-memory-restart of 400MB, and define a deploy section that pulls from git and runs npm ci before restarting.
- Prompt 50: Write a GitHub Actions deployment pipeline for an Express.js API. Run lint and tests in parallel on every push. On merge to main, build a Docker image, push to a registry with the commit SHA as the tag, SSH into the VPS, pull the new image, run database migrations, perform a health check on the new container before routing traffic to it, and roll back automatically if the health check fails.
FAQ
Do these prompts work with Express 5?
Most work with Express 5 without modification. Express 5 natively handles async route handlers that throw, so you can remove the asyncHandler wrapper from Prompt 12. The route method signatures and middleware system are backward compatible. Specify Express 5 in your prompt to get the updated async handling pattern.
Should I use Express.js or switch to Fastify or Hono?
Express is the right choice if you need the largest ecosystem of compatible middleware, have existing Express code to extend, or want the most documentation and community answers available. Fastify is worth considering if you need measurably better throughput for high-volume APIs. Hono is a good choice for edge runtimes. For most new projects, the difference in production is small.
Which database should I use with Express.js?
There is no official pairing. MongoDB with Mongoose is common for document data and rapid schema iteration. PostgreSQL with node-postgres or Prisma is better for relational data with integrity requirements. The prompts in this list cover both. Choose based on your data model, not convention.
How do I structure a large Express.js application?
The controller-service-repository pattern from Prompts 9-11 scales well. Controllers handle HTTP, services contain business logic, and repositories handle database access. Each layer is independently testable. For very large applications, group by domain (users, products, orders) rather than by layer (controllers, services, models) — domain grouping makes it easier to work on one feature without touching unrelated files.
Are these prompts suitable for a beginner?
Yes, but work through them in order and understand each output before moving on. Prompts 1-8 are the foundation. If you run Prompt 15 without understanding Prompt 3, the generated code will reference middleware patterns you have not set up. The glossary in Prompt 1 is especially useful if Express concepts like middleware chaining or next() are new to you.
Related free tools
If you want to turn this topic into action, use one of ShortIQ's free tools for campaign planning, UTM structure, or QR distribution.
Continue Reading
Explore more guides on link shortener SaaS strategy, Bitly alternatives, and white label link management.
Free newsletter
Get new guides in your inbox
We publish practical guides on dev tooling, prompt engineering, marketing workflows, and deployment. No fluff — straight to the point.
No spam. Unsubscribe any time.
Was this article helpful?
Tell us if this guide solved the problem or what was still missing. We use this to improve the blog and only follow up if you explicitly allow it.