10 Prompts for Node.js and Express: API, Middleware, and Authentication

Introduction

Node.js and Express remain the backbone of modern backend development in 2026. Whether you're building a RESTful API, implementing secure authentication, or handling real-time WebSocket connections, the right prompt can save hours of debugging and boilerplate code. This article provides 10 ready-to-use prompts for Node.js and Express, covering API design, middleware patterns, authentication flows, and WebSocket integration. Each prompt is crafted to be copy-paste ready and includes a practical example to illustrate its use. These prompts are based on current best practices from the official Express documentation (expressjs.com) and Node.js API docs (nodejs.org).

Why Use Prompts for Node.js Development?

Prompts act as reusable templates that accelerate development. Instead of writing every route handler from scratch, you can adapt proven patterns. According to the Node.js Foundation's 2025 survey, over 70% of professional Node.js developers use some form of code snippets or generators to speed up API creation. The prompts below follow the Express routing and middleware conventions, ensuring compatibility with Express 4.x and 5.x (stable as of 2026). For authentication, we rely on jsonwebtoken (JWT) and bcrypt — both actively maintained. For WebSocket, we use the ws library, as Socket.IO remains popular but is heavier for simple real-time features.

10 Ready-to-Use Prompts for Node.js and Express

1. Express Server with Basic Middleware

Task: Set up a minimal Express server with JSON body parsing, CORS, and request logging.

Prompt:

Create an Express server script that:
- Imports express, cors, and morgan
- Enables CORS for all origins
- Uses morgan('dev') for request logging
- Parses JSON bodies with express.json()
- Listens on port 3000
- Includes a health check route GET /health returning { status: 'ok' }

Example Output:

const express = require('express');
const cors = require('cors');
const morgan = require('morgan');

const app = express();

app.use(cors());
app.use(morgan('dev'));
app.use(express.json());

app.get('/health', (req, res) => {
  res.json({ status: 'ok' });
});

app.listen(3000, () => console.log('Server running on port 3000'));

2. REST API with CRUD Routes

Task: Generate a set of RESTful routes for a resource (e.g., users).

Prompt:

Generate Express routes for a User resource with:
- GET /users  list all users
- GET /users/:id  get a single user
- POST /users  create a user (validate name and email)
- PUT /users/:id  update a user
- DELETE /users/:id  delete a user
Use an in-memory array as the data store. Include try-catch for error handling.

Example Output (snippet):

const express = require('express');
const router = express.Router();

let users = [];
let nextId = 1;

router.get('/', (req, res) => {
  res.json(users);
});

router.post('/', (req, res) => {
  const { name, email } = req.body;
  if (!name || !email) return res.status(400).json({ error: 'Name and email required' });
  const user = { id: nextId++, name, email };
  users.push(user);
  res.status(201).json(user);
});

3. JWT Authentication Middleware

Task: Create middleware that verifies a JWT token from the Authorization header.

Prompt:

Write an Express middleware function called authenticateJWT that:
- Extracts the token from the 'Authorization' header (format: 'Bearer <token>')
- Verifies the token using jsonwebtoken with a secret key from process.env.JWT_SECRET
- If valid, attaches decoded user data to req.user and calls next()
- If missing or invalid, returns 401 with error message
- Use try-catch for verification errors

Example Output:

const jwt = require('jsonwebtoken');

function authenticateJWT(req, res, next) {
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return res.status(401).json({ error: 'Access denied. No token provided.' });
  }
  const token = authHeader.split(' ')[1];
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (err) {
    return res.status(401).json({ error: 'Invalid token.' });
  }
}

4. User Registration with Password Hashing

Task: Implement a registration endpoint that hashes passwords securely.

Prompt:

Create a POST /register route that:
- Accepts username, email, and password in the request body
- Validates that password is at least 8 characters
- Hashes the password using bcrypt with 10 salt rounds
- Saves user (with hashed password) to an array
- Returns 201 with user data (excluding password)
- Handles duplicate email errors

Example Output:

const bcrypt = require('bcrypt');

router.post('/register', async (req, res) => {
  const { username, email, password } = req.body;
if (!username

|| !email || !password) return res.status(400).json({ error: 'All fields required' });
  if (password.length < 8) return res.status(400).json({ error: 'Password must be at least 8 characters' });
  const existingUser = users.find(u => u.email === email);
  if (existingUser) return res.status(409).json({ error: 'Email already registered' });
  const hashedPassword = await bcrypt.hash(password, 10);
  const user = { id: nextId++, username, email, password: hashedPassword };
  users.push(user);
  res.status(201).json({ id: user.id, username, email });
});

5. Login and Token Generation

Task: Create a login endpoint that returns a JWT token.

Prompt:

Write a POST /login route that:
- Accepts email and password
- Finds the user by email (from an in-memory store)
- Compares password using bcrypt.compare
- If valid, generates a JWT token with user id and email (expires in 1 hour) using jsonwebtoken
- Returns { token, user: { id, email } }
- If invalid credentials, returns 401

Example Output:

router.post('/login', async (req, res) => {
  const { email, password } = req.body;
  const user = users.find(u => u.email === email);
  if (!user) return res.status(401).json({ error: 'Invalid email or password' });
  const validPassword = await bcrypt.compare(password, user.password);
  if (!validPassword) return res.status(401).json({ error: 'Invalid email or password' });
  const token = jwt.sign({ id: user.id, email: user.email }, process.env.JWT_SECRET, { expiresIn: '1h' });
  res.json({ token, user: { id: user.id, email: user.email } });
});

6. Error Handling Middleware

Task: Build a centralized error handler for Express.

Prompt:

Create an Express error-handling middleware that:
- Takes four parameters (err, req, res, next)
- Logs the error stack in development mode (process.env.NODE_ENV === 'development')
- Returns a JSON response with status 500 and message 'Internal Server Error'
- For custom errors with a 'statusCode' property, uses that status code
- Exports the middleware function

Example Output:

function errorHandler(err, req, res, next) {
  if (process.env.NODE_ENV === 'development') {
    console.error(err.stack);
  }
  const statusCode = err.statusCode || 500;
  res.status(statusCode).json({
    error: statusCode === 500 ? 'Internal Server Error' : err.message
  });
}

module.exports = errorHandler;

7. Rate Limiting Middleware

Task: Implement a simple in-memory rate limiter for API endpoints.

Prompt:

Write Express middleware that limits requests per IP to 100 per 15 minutes:
- Store request counts in a Map with IP as key
- Include a timer to reset counters every 15 minutes
- If limit exceeded, return 429 with 'Too Many Requests'
- Otherwise, call next()

Example Output:

const rateLimitMap = new Map();
const WINDOW_MS = 15 * 60 * 1000;
const MAX_REQUESTS = 100;

setInterval(() => {
  rateLimitMap.clear();
}, WINDOW_MS);

function rateLimiter(req, res, next) {
  const ip = req.ip;
  const count = rateLimitMap.get(ip) || 0;
  if (count >= MAX_REQUESTS) {
    return res.status(429).json({ error: 'Too Many Requests' });
  }
  rateLimitMap.set(ip, count + 1);
  next();
}

8. WebSocket Server with Express Integration

Task: Set up a WebSocket server alongside Express using the ws library.

Prompt:

Create a WebSocket server that:
- Uses the 'ws' library
- Attaches to the same HTTP server as Express (use http.createServer)
- On connection, logs 'Client connected' and sends a welcome message
- On message, echoes the message back to the client
- On close, logs 'Client disconnected'
- Handles errors gracefully

Example Output:

const http = require('http');
const WebSocket = require('ws');

const server = http.createServer(app);
const wss = new WebSocket.Server({ server });

wss.on('connection', (ws) => {
  console.log('Client connected');
  ws.send('Welcome to the WebSocket server!');

  ws.on('message', (message) => {
    console.log(`Received: ${message}`);
    ws.send(`Echo: ${message}`);
  });

  ws.on('close', () => console.log('Client disconnected'));
  ws.on('error', (err) => console.error('WebSocket error:', err));
});

server.listen(3000, () => console.log('Server with WebSocket listening on port 3000'));

9. CORS Configuration for Specific Origins

Task: Configure CORS to allow only a specific frontend domain.

Prompt:

Configure CORS middleware to:
- Allow requests only from 'https://myapp.example.com'
- Allow methods: GET, POST, PUT, DELETE
- Allow headers: Content-Type, Authorization
- Allow credentials (cookies)
- Set max age to 86400 seconds

Example Output:

const corsOptions = {
  origin: 'https://myapp.example.com',
  methods: ['GET', 'POST', 'PUT', 'DELETE'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true,
  maxAge: 86400
};

app.use(cors(corsOptions));

10. Environment Configuration with dotenv

Task: Load environment variables from a .env file and set defaults.

Prompt:

Create a config module that:
- Loads .env file using dotenv at the top of the application
- Exports an object with: PORT (default 3000), JWT_SECRET (required), DB_URL (default 'mongodb://localhost:27017/mydb'), NODE_ENV (default 'development')
- Throws an error if JWT_SECRET is not set

Example Output:

require('dotenv').config();

const config = {
  PORT: process.env.PORT || 3000,
  JWT_SECRET: process.env.JWT_SECRET,
  DB_URL: process.env.DB_URL || 'mongodb://localhost:27017/mydb',
  NODE_ENV: process.env.NODE_ENV || 'development'
};

if (!config.JWT_SECRET) {
  throw new Error('JWT_SECRET environment variable is required');
}

module.exports = config;

Practical Use Cases: Real-World Examples

Many companies build production APIs using these patterns. For instance, a fintech startup might use the JWT authentication middleware (Prompt 3) to secure endpoints, combined with rate limiting (Prompt 7) to prevent abuse. A real-time dashboard application could integrate WebSocket (Prompt 8) to live-update stock prices. ASI Biont supports integration with such real-time data services via API — more details on connecting external systems can be found at asibiont.com/courses.

Conclusion

These 10 prompts cover the most common tasks in Node.js and Express development: setting up a server, building REST APIs, implementing authentication with JWT and bcrypt, handling errors, rate limiting, WebSocket communication, and secure configuration. By adapting these templates, you can reduce boilerplate and focus on business logic. Always follow security best practices: use environment variables for secrets, hash passwords, validate input, and keep dependencies updated. For further learning, refer to the official Express guide (expressjs.com/en/guide/error-handling.html) and Node.js documentation (nodejs.org).

← All posts

Comments