
Nodejs Backend Patterns
- 1 installs
- 404 repo stars
- Updated August 5, 2026
- aiskillstore/marketplace
This is a copy of nodejs-backend-patterns by rmyndharis - installs and ranking accrue to the original listing.
nodejs-backend-patterns is a Claude Code skill that guides building production Node.js backend services and APIs with Express or Fastify.
About
nodejs-backend-patterns is a Claude Code skill for building production Node.js backend services. It covers Express and Fastify middleware patterns, error handling, authentication and authorization, SQL and NoSQL database integration, REST and GraphQL API design, WebSockets, and background job processing. A developer uses it when creating Node.js servers, REST APIs, or microservices.
- Guides building Node.js backends with Express/Fastify, middleware, and error handling
- Covers REST/GraphQL APIs, auth, database integration, and microservices
- Ships a resources/implementation-playbook.md with detailed patterns
Nodejs Backend Patterns by the numbers
- 1 all-time installs (skills.sh)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
nodejs-backend-patterns capabilities & compatibility
- Capabilities
- api development · backend · auth setup · database integration
- Use cases
- api development · database
- IDEs
- vscode · cursor ide
- Pricing
- Free
What nodejs-backend-patterns says it does
Build production-ready Node.js backend services with Express/Fastify, implementing middleware patterns, error handling, authentication, database integration, and API design best practices.
Use when creating Node.js servers, REST APIs, GraphQL backends, or microservices architectures.
npx skills add https://github.com/aiskillstore/marketplace --skill nodejs-backend-patternsAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 404 |
| Last updated | August 5, 2026 |
| Repository | aiskillstore/marketplace ↗ |
What it does
Build production Node.js REST/GraphQL APIs and microservices with middleware, auth, and database integration.
Who is it for?
Developers building Node.js REST/GraphQL APIs, microservices, or backend services
Skip if: Tasks unrelated to Node.js backend development
When should I use this skill?
creating Node.js servers, REST APIs, GraphQL backends, or microservices
What you get
A Node.js backend service is built with production patterns for middleware, error handling, auth, and database integration.
- resources/implementation-playbook.md with detailed patterns
By the numbers
- 8 use-when scenarios listed
- 1 implementation playbook resource
Files
Node.js Backend Patterns
Comprehensive guidance for building scalable, maintainable, and production-ready Node.js backend applications with modern frameworks, architectural patterns, and best practices.
Use this skill when
- Building REST APIs or GraphQL servers
- Creating microservices with Node.js
- Implementing authentication and authorization
- Designing scalable backend architectures
- Setting up middleware and error handling
- Integrating databases (SQL and NoSQL)
- Building real-time applications with WebSockets
- Implementing background job processing
Do not use this skill when
- The task is unrelated to node.js backend patterns
- You need a different domain or tool outside this scope
Instructions
- Clarify goals, constraints, and required inputs.
- Apply relevant best practices and validate outcomes.
- Provide actionable steps and verification.
- If detailed examples are required, open
resources/implementation-playbook.md.
Resources
resources/implementation-playbook.mdfor detailed patterns and examples.
Node.js Backend Patterns Implementation Playbook
This file contains detailed patterns, checklists, and code samples referenced by the skill.
Node.js Backend Patterns
Comprehensive guidance for building scalable, maintainable, and production-ready Node.js backend applications with modern frameworks, architectural patterns, and best practices.
When to Use This Skill
- Building REST APIs or GraphQL servers
- Creating microservices with Node.js
- Implementing authentication and authorization
- Designing scalable backend architectures
- Setting up middleware and error handling
- Integrating databases (SQL and NoSQL)
- Building real-time applications with WebSockets
- Implementing background job processing
Core Frameworks
Express.js - Minimalist Framework
Basic Setup:
import express, { Request, Response, NextFunction } from 'express';
import helmet from 'helmet';
import cors from 'cors';
import compression from 'compression';
const app = express();
// Security middleware
app.use(helmet());
app.use(cors({ origin: process.env.ALLOWED_ORIGINS?.split(',') }));
app.use(compression());
// Body parsing
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
// Request logging
app.use((req: Request, res: Response, next: NextFunction) => {
console.log(`${req.method} ${req.path}`);
next();
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});Fastify - High Performance Framework
Basic Setup:
import Fastify from 'fastify';
import helmet from '@fastify/helmet';
import cors from '@fastify/cors';
import compress from '@fastify/compress';
const fastify = Fastify({
logger: {
level: process.env.LOG_LEVEL || 'info',
transport: {
target: 'pino-pretty',
options: { colorize: true }
}
}
});
// Plugins
await fastify.register(helmet);
await fastify.register(cors, { origin: true });
await fastify.register(compress);
// Type-safe routes with schema validation
fastify.post<{
Body: { name: string; email: string };
Reply: { id: string; name: string };
}>('/users', {
schema: {
body: {
type: 'object',
required: ['name', 'email'],
properties: {
name: { type: 'string', minLength: 1 },
email: { type: 'string', format: 'email' }
}
}
}
}, async (request, reply) => {
const { name, email } = request.body;
return { id: '123', name };
});
await fastify.listen({ port: 3000, host: '0.0.0.0' });Architectural Patterns
Pattern 1: Layered Architecture
Structure:
src/
├── controllers/ # Handle HTTP requests/responses
├── services/ # Business logic
├── repositories/ # Data access layer
├── models/ # Data models
├── middleware/ # Express/Fastify middleware
├── routes/ # Route definitions
├── utils/ # Helper functions
├── config/ # Configuration
└── types/ # TypeScript typesController Layer:
// controllers/user.controller.ts
import { Request, Response, NextFunction } from 'express';
import { UserService } from '../services/user.service';
import { CreateUserDTO, UpdateUserDTO } from '../types/user.types';
export class UserController {
constructor(private userService: UserService) {}
async createUser(req: Request, res: Response, next: NextFunction) {
try {
const userData: CreateUserDTO = req.body;
const user = await this.userService.createUser(userData);
res.status(201).json(user);
} catch (error) {
next(error);
}
}
async getUser(req: Request, res: Response, next: NextFunction) {
try {
const { id } = req.params;
const user = await this.userService.getUserById(id);
res.json(user);
} catch (error) {
next(error);
}
}
async updateUser(req: Request, res: Response, next: NextFunction) {
try {
const { id } = req.params;
const updates: UpdateUserDTO = req.body;
const user = await this.userService.updateUser(id, updates);
res.json(user);
} catch (error) {
next(error);
}
}
async deleteUser(req: Request, res: Response, next: NextFunction) {
try {
const { id } = req.params;
await this.userService.deleteUser(id);
res.status(204).send();
} catch (error) {
next(error);
}
}
}Service Layer:
// services/user.service.ts
import { UserRepository } from '../repositories/user.repository';
import { CreateUserDTO, UpdateUserDTO, User } from '../types/user.types';
import { NotFoundError, ValidationError } from '../utils/errors';
import bcrypt from 'bcrypt';
export class UserService {
constructor(private userRepository: UserRepository) {}
async createUser(userData: CreateUserDTO): Promise<User> {
// Validation
const existingUser = await this.userRepository.findByEmail(userData.email);
if (existingUser) {
throw new ValidationError('Email already exists');
}
// Hash password
const hashedPassword = await bcrypt.hash(userData.password, 10);
// Create user
const user = await this.userRepository.create({
...userData,
password: hashedPassword
});
// Remove password from response
const { password, ...userWithoutPassword } = user;
return userWithoutPassword as User;
}
async getUserById(id: string): Promise<User> {
const user = await this.userRepository.findById(id);
if (!user) {
throw new NotFoundError('User not found');
}
const { password, ...userWithoutPassword } = user;
return userWithoutPassword as User;
}
async updateUser(id: string, updates: UpdateUserDTO): Promise<User> {
const user = await this.userRepository.update(id, updates);
if (!user) {
throw new NotFoundError('User not found');
}
const { password, ...userWithoutPassword } = user;
return userWithoutPassword as User;
}
async deleteUser(id: string): Promise<void> {
const deleted = await this.userRepository.delete(id);
if (!deleted) {
throw new NotFoundError('User not found');
}
}
}Repository Layer:
// repositories/user.repository.ts
import { Pool } from 'pg';
import { CreateUserDTO, UpdateUserDTO, UserEntity } from '../types/user.types';
export class UserRepository {
constructor(private db: Pool) {}
async create(userData: CreateUserDTO & { password: string }): Promise<UserEntity> {
const query = `
INSERT INTO users (name, email, password)
VALUES ($1, $2, $3)
RETURNING id, name, email, password, created_at, updated_at
`;
const { rows } = await this.db.query(query, [
userData.name,
userData.email,
userData.password
]);
return rows[0];
}
async findById(id: string): Promise<UserEntity | null> {
const query = 'SELECT * FROM users WHERE id = $1';
const { rows } = await this.db.query(query, [id]);
return rows[0] || null;
}
async findByEmail(email: string): Promise<UserEntity | null> {
const query = 'SELECT * FROM users WHERE email = $1';
const { rows } = await this.db.query(query, [email]);
return rows[0] || null;
}
async update(id: string, updates: UpdateUserDTO): Promise<UserEntity | null> {
const fields = Object.keys(updates);
const values = Object.values(updates);
const setClause = fields
.map((field, idx) => `${field} = $${idx + 2}`)
.join(', ');
const query = `
UPDATE users
SET ${setClause}, updated_at = CURRENT_TIMESTAMP
WHERE id = $1
RETURNING *
`;
const { rows } = await this.db.query(query, [id, ...values]);
return rows[0] || null;
}
async delete(id: string): Promise<boolean> {
const query = 'DELETE FROM users WHERE id = $1';
const { rowCount } = await this.db.query(query, [id]);
return rowCount > 0;
}
}Pattern 2: Dependency Injection
DI Container:
// di-container.ts
import { Pool } from 'pg';
import { UserRepository } from './repositories/user.repository';
import { UserService } from './services/user.service';
import { UserController } from './controllers/user.controller';
import { AuthService } from './services/auth.service';
class Container {
private instances = new Map<string, any>();
register<T>(key: string, factory: () => T): void {
this.instances.set(key, factory);
}
resolve<T>(key: string): T {
const factory = this.instances.get(key);
if (!factory) {
throw new Error(`No factory registered for ${key}`);
}
return factory();
}
singleton<T>(key: string, factory: () => T): void {
let instance: T;
this.instances.set(key, () => {
if (!instance) {
instance = factory();
}
return instance;
});
}
}
export const container = new Container();
// Register dependencies
container.singleton('db', () => new Pool({
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT || '5432'),
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
}));
container.singleton('userRepository', () =>
new UserRepository(container.resolve('db'))
);
container.singleton('userService', () =>
new UserService(container.resolve('userRepository'))
);
container.register('userController', () =>
new UserController(container.resolve('userService'))
);
container.singleton('authService', () =>
new AuthService(container.resolve('userRepository'))
);Middleware Patterns
Authentication Middleware
// middleware/auth.middleware.ts
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
import { UnauthorizedError } from '../utils/errors';
interface JWTPayload {
userId: string;
email: string;
}
declare global {
namespace Express {
interface Request {
user?: JWTPayload;
}
}
}
export const authenticate = async (
req: Request,
res: Response,
next: NextFunction
) => {
try {
const token = req.headers.authorization?.replace('Bearer ', '');
if (!token) {
throw new UnauthorizedError('No token provided');
}
const payload = jwt.verify(
token,
process.env.JWT_SECRET!
) as JWTPayload;
req.user = payload;
next();
} catch (error) {
next(new UnauthorizedError('Invalid token'));
}
};
export const authorize = (...roles: string[]) => {
return async (req: Request, res: Response, next: NextFunction) => {
if (!req.user) {
return next(new UnauthorizedError('Not authenticated'));
}
// Check if user has required role
const hasRole = roles.some(role =>
req.user?.roles?.includes(role)
);
if (!hasRole) {
return next(new UnauthorizedError('Insufficient permissions'));
}
next();
};
};Validation Middleware
// middleware/validation.middleware.ts
import { Request, Response, NextFunction } from 'express';
import { AnyZodObject, ZodError } from 'zod';
import { ValidationError } from '../utils/errors';
export const validate = (schema: AnyZodObject) => {
return async (req: Request, res: Response, next: NextFunction) => {
try {
await schema.parseAsync({
body: req.body,
query: req.query,
params: req.params
});
next();
} catch (error) {
if (error instanceof ZodError) {
const errors = error.errors.map(err => ({
field: err.path.join('.'),
message: err.message
}));
next(new ValidationError('Validation failed', errors));
} else {
next(error);
}
}
};
};
// Usage with Zod
import { z } from 'zod';
const createUserSchema = z.object({
body: z.object({
name: z.string().min(1),
email: z.string().email(),
password: z.string().min(8)
})
});
router.post('/users', validate(createUserSchema), userController.createUser);Rate Limiting Middleware
// middleware/rate-limit.middleware.ts
import rateLimit from 'express-rate-limit';
import RedisStore from 'rate-limit-redis';
import Redis from 'ioredis';
const redis = new Redis({
host: process.env.REDIS_HOST,
port: parseInt(process.env.REDIS_PORT || '6379')
});
export const apiLimiter = rateLimit({
store: new RedisStore({
client: redis,
prefix: 'rl:',
}),
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // Limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP, please try again later',
standardHeaders: true,
legacyHeaders: false,
});
export const authLimiter = rateLimit({
store: new RedisStore({
client: redis,
prefix: 'rl:auth:',
}),
windowMs: 15 * 60 * 1000,
max: 5, // Stricter limit for auth endpoints
skipSuccessfulRequests: true,
});Request Logging Middleware
// middleware/logger.middleware.ts
import { Request, Response, NextFunction } from 'express';
import pino from 'pino';
const logger = pino({
level: process.env.LOG_LEVEL || 'info',
transport: {
target: 'pino-pretty',
options: { colorize: true }
}
});
export const requestLogger = (
req: Request,
res: Response,
next: NextFunction
) => {
const start = Date.now();
// Log response when finished
res.on('finish', () => {
const duration = Date.now() - start;
logger.info({
method: req.method,
url: req.url,
status: res.statusCode,
duration: `${duration}ms`,
userAgent: req.headers['user-agent'],
ip: req.ip
});
});
next();
};
export { logger };Error Handling
Custom Error Classes
// utils/errors.ts
export class AppError extends Error {
constructor(
public message: string,
public statusCode: number = 500,
public isOperational: boolean = true
) {
super(message);
Object.setPrototypeOf(this, AppError.prototype);
Error.captureStackTrace(this, this.constructor);
}
}
export class ValidationError extends AppError {
constructor(message: string, public errors?: any[]) {
super(message, 400);
}
}
export class NotFoundError extends AppError {
constructor(message: string = 'Resource not found') {
super(message, 404);
}
}
export class UnauthorizedError extends AppError {
constructor(message: string = 'Unauthorized') {
super(message, 401);
}
}
export class ForbiddenError extends AppError {
constructor(message: string = 'Forbidden') {
super(message, 403);
}
}
export class ConflictError extends AppError {
constructor(message: string) {
super(message, 409);
}
}Global Error Handler
// middleware/error-handler.ts
import { Request, Response, NextFunction } from 'express';
import { AppError } from '../utils/errors';
import { logger } from './logger.middleware';
export const errorHandler = (
err: Error,
req: Request,
res: Response,
next: NextFunction
) => {
if (err instanceof AppError) {
return res.status(err.statusCode).json({
status: 'error',
message: err.message,
...(err instanceof ValidationError && { errors: err.errors })
});
}
// Log unexpected errors
logger.error({
error: err.message,
stack: err.stack,
url: req.url,
method: req.method
});
// Don't leak error details in production
const message = process.env.NODE_ENV === 'production'
? 'Internal server error'
: err.message;
res.status(500).json({
status: 'error',
message
});
};
// Async error wrapper
export const asyncHandler = (
fn: (req: Request, res: Response, next: NextFunction) => Promise<any>
) => {
return (req: Request, res: Response, next: NextFunction) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
};Database Patterns
PostgreSQL with Connection Pool
// config/database.ts
import { Pool, PoolConfig } from 'pg';
const poolConfig: PoolConfig = {
host: process.env.DB_HOST,
port: parseInt(process.env.DB_PORT || '5432'),
database: process.env.DB_NAME,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
};
export const pool = new Pool(poolConfig);
// Test connection
pool.on('connect', () => {
console.log('Database connected');
});
pool.on('error', (err) => {
console.error('Unexpected database error', err);
process.exit(-1);
});
// Graceful shutdown
export const closeDatabase = async () => {
await pool.end();
console.log('Database connection closed');
};MongoDB with Mongoose
// config/mongoose.ts
import mongoose from 'mongoose';
const connectDB = async () => {
try {
await mongoose.connect(process.env.MONGODB_URI!, {
maxPoolSize: 10,
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 45000,
});
console.log('MongoDB connected');
} catch (error) {
console.error('MongoDB connection error:', error);
process.exit(1);
}
};
mongoose.connection.on('disconnected', () => {
console.log('MongoDB disconnected');
});
mongoose.connection.on('error', (err) => {
console.error('MongoDB error:', err);
});
export { connectDB };
// Model example
import { Schema, model, Document } from 'mongoose';
interface IUser extends Document {
name: string;
email: string;
password: string;
createdAt: Date;
updatedAt: Date;
}
const userSchema = new Schema<IUser>({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
}, {
timestamps: true
});
// Indexes
userSchema.index({ email: 1 });
export const User = model<IUser>('User', userSchema);Transaction Pattern
// services/order.service.ts
import { Pool } from 'pg';
export class OrderService {
constructor(private db: Pool) {}
async createOrder(userId: string, items: any[]) {
const client = await this.db.connect();
try {
await client.query('BEGIN');
// Create order
const orderResult = await client.query(
'INSERT INTO orders (user_id, total) VALUES ($1, $2) RETURNING id',
[userId, calculateTotal(items)]
);
const orderId = orderResult.rows[0].id;
// Create order items
for (const item of items) {
await client.query(
'INSERT INTO order_items (order_id, product_id, quantity, price) VALUES ($1, $2, $3, $4)',
[orderId, item.productId, item.quantity, item.price]
);
// Update inventory
await client.query(
'UPDATE products SET stock = stock - $1 WHERE id = $2',
[item.quantity, item.productId]
);
}
await client.query('COMMIT');
return orderId;
} catch (error) {
await client.query('ROLLBACK');
throw error;
} finally {
client.release();
}
}
}Authentication & Authorization
JWT Authentication
// services/auth.service.ts
import jwt from 'jsonwebtoken';
import bcrypt from 'bcrypt';
import { UserRepository } from '../repositories/user.repository';
import { UnauthorizedError } from '../utils/errors';
export class AuthService {
constructor(private userRepository: UserRepository) {}
async login(email: string, password: string) {
const user = await this.userRepository.findByEmail(email);
if (!user) {
throw new UnauthorizedError('Invalid credentials');
}
const isValid = await bcrypt.compare(password, user.password);
if (!isValid) {
throw new UnauthorizedError('Invalid credentials');
}
const token = this.generateToken({
userId: user.id,
email: user.email
});
const refreshToken = this.generateRefreshToken({
userId: user.id
});
return {
token,
refreshToken,
user: {
id: user.id,
name: user.name,
email: user.email
}
};
}
async refreshToken(refreshToken: string) {
try {
const payload = jwt.verify(
refreshToken,
process.env.REFRESH_TOKEN_SECRET!
) as { userId: string };
const user = await this.userRepository.findById(payload.userId);
if (!user) {
throw new UnauthorizedError('User not found');
}
const token = this.generateToken({
userId: user.id,
email: user.email
});
return { token };
} catch (error) {
throw new UnauthorizedError('Invalid refresh token');
}
}
private generateToken(payload: any): string {
return jwt.sign(payload, process.env.JWT_SECRET!, {
expiresIn: '15m'
});
}
private generateRefreshToken(payload: any): string {
return jwt.sign(payload, process.env.REFRESH_TOKEN_SECRET!, {
expiresIn: '7d'
});
}
}Caching Strategies
// utils/cache.ts
import Redis from 'ioredis';
const redis = new Redis({
host: process.env.REDIS_HOST,
port: parseInt(process.env.REDIS_PORT || '6379'),
retryStrategy: (times) => {
const delay = Math.min(times * 50, 2000);
return delay;
}
});
export class CacheService {
async get<T>(key: string): Promise<T | null> {
const data = await redis.get(key);
return data ? JSON.parse(data) : null;
}
async set(key: string, value: any, ttl?: number): Promise<void> {
const serialized = JSON.stringify(value);
if (ttl) {
await redis.setex(key, ttl, serialized);
} else {
await redis.set(key, serialized);
}
}
async delete(key: string): Promise<void> {
await redis.del(key);
}
async invalidatePattern(pattern: string): Promise<void> {
const keys = await redis.keys(pattern);
if (keys.length > 0) {
await redis.del(...keys);
}
}
}
// Cache decorator
export function Cacheable(ttl: number = 300) {
return function (
target: any,
propertyKey: string,
descriptor: PropertyDescriptor
) {
const originalMethod = descriptor.value;
descriptor.value = async function (...args: any[]) {
const cache = new CacheService();
const cacheKey = `${propertyKey}:${JSON.stringify(args)}`;
const cached = await cache.get(cacheKey);
if (cached) {
return cached;
}
const result = await originalMethod.apply(this, args);
await cache.set(cacheKey, result, ttl);
return result;
};
return descriptor;
};
}API Response Format
// utils/response.ts
import { Response } from 'express';
export class ApiResponse {
static success<T>(res: Response, data: T, message?: string, statusCode = 200) {
return res.status(statusCode).json({
status: 'success',
message,
data
});
}
static error(res: Response, message: string, statusCode = 500, errors?: any) {
return res.status(statusCode).json({
status: 'error',
message,
...(errors && { errors })
});
}
static paginated<T>(
res: Response,
data: T[],
page: number,
limit: number,
total: number
) {
return res.json({
status: 'success',
data,
pagination: {
page,
limit,
total,
pages: Math.ceil(total / limit)
}
});
}
}Best Practices
1. Use TypeScript: Type safety prevents runtime errors 2. Implement proper error handling: Use custom error classes 3. Validate input: Use libraries like Zod or Joi 4. Use environment variables: Never hardcode secrets 5. Implement logging: Use structured logging (Pino, Winston) 6. Add rate limiting: Prevent abuse 7. Use HTTPS: Always in production 8. Implement CORS properly: Don't use * in production 9. Use dependency injection: Easier testing and maintenance 10. Write tests: Unit, integration, and E2E tests 11. Handle graceful shutdown: Clean up resources 12. Use connection pooling: For databases 13. Implement health checks: For monitoring 14. Use compression: Reduce response size 15. Monitor performance: Use APM tools
Testing Patterns
See javascript-testing-patterns skill for comprehensive testing guidance.
Resources
- Node.js Best Practices: https://github.com/goldbergyoni/nodebestpractices
- Express.js Guide: https://expressjs.com/en/guide/
- Fastify Documentation: https://www.fastify.io/docs/
- TypeScript Node Starter: https://github.com/microsoft/TypeScript-Node-Starter
{
"schema_version": "2.0",
"meta": {
"generated_at": "2026-02-24T16:31:27.845Z",
"slug": "sickn33-nodejs-backend-patterns",
"source_url": "https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/nodejs-backend-patterns",
"source_ref": "main",
"model": "claude",
"analysis_version": "3.0.0",
"source_type": "community",
"content_hash": "a1d9ad4dfda00dd72aefbbc76039f83e0f9f490e7140a35e1d0f0844c77993f2",
"tree_hash": "1d8afb344dd87e279175aa248f9eb22908927f73359a556a222b8384bffbb981"
},
"skill": {
"name": "nodejs-backend-patterns",
"description": "Build production-ready Node.js backend services with Express/Fastify, implementing middleware patterns, error handling, authentication, database integration, and API design best practices.",
"summary": "Comprehensive guidance for building scalable Node.js backend applications with modern frameworks and architectural patterns.",
"icon": "📦",
"version": "1.0.1",
"author": "sickn33",
"license": "MIT",
"category": "coding",
"tags": [
"nodejs",
"express",
"fastify",
"backend",
"api"
],
"supported_tools": [
"claude",
"codex",
"claude-code"
],
"risk_factors": []
},
"security_audit": {
"risk_level": "safe",
"is_blocked": false,
"safe_to_publish": true,
"summary": "This is an educational/documentation skill providing Node.js backend development guidance through markdown code examples. All static analysis findings are false positives - the detected patterns are instructional code samples in markdown format, not executable skill logic. No actual security risks detected.",
"risk_factor_evidence": [],
"critical_findings": [],
"high_findings": [],
"medium_findings": [],
"low_findings": [],
"dangerous_patterns": [],
"files_scanned": 2,
"total_lines": 1058,
"audit_model": "claude",
"audited_at": "2026-02-24T16:31:27.845Z"
},
"content": {
"user_title": "Build Production-Ready Node.js Backend Services",
"value_statement": "Creating robust Node.js backends requires understanding complex architectural patterns and best practices. This skill provides comprehensive guidance for building scalable, secure backend services with modern frameworks.",
"seo_keywords": [
"Node.js",
"Express.js",
"Fastify",
"backend development",
"REST API",
"TypeScript",
"Claude",
"Codex",
"Claude Code",
"microservices"
],
"actual_capabilities": [
"Guide Express.js and Fastify project setup with security middleware",
"Implement layered architecture patterns (controllers, services, repositories)",
"Design authentication and authorization systems with JWT",
"Create database integration patterns for PostgreSQL and MongoDB",
"Implement error handling, logging, and rate limiting middleware",
"Provide code examples for caching, transactions, and dependency injection"
],
"limitations": [
"Provides guidance and code examples, not executable automation",
"Does not replace the need for security review of production code",
"Examples may need adaptation for specific project requirements",
"Does not cover frontend integration or deployment strategies"
],
"use_cases": [
{
"title": "API Development",
"description": "Build REST or GraphQL APIs with proper middleware, validation, and error handling for production applications.",
"target_user": "Backend developers building web service APIs"
},
{
"title": "Microservices Architecture",
"description": "Design scalable microservices with dependency injection, proper logging, and inter-service communication patterns.",
"target_user": "Architects and senior developers designing distributed systems"
},
{
"title": "Learning Modern Node.js",
"description": "Learn industry-standard patterns for authentication, database access, caching, and error handling in Node.js applications.",
"target_user": "Junior developers transitioning to backend development"
}
],
"prompt_templates": [
{
"title": "Basic Express Setup",
"prompt": "Help me create a basic Express.js server with security middleware, request logging, and error handling. Include TypeScript types and proper configuration.",
"scenario": "Starting a new Node.js API project"
},
{
"title": "Authentication System",
"prompt": "Design a JWT-based authentication system with login, registration, and token refresh endpoints. Include password hashing with bcrypt and proper error handling.",
"scenario": "Adding user authentication to an existing API"
},
{
"title": "Database Layer Design",
"prompt": "Create a repository pattern implementation for PostgreSQL with connection pooling, parameterized queries, and transaction support for an order management system.",
"scenario": "Building data access layer for an e-commerce application"
},
{
"title": "Complete Microservice",
"prompt": "Design a complete microservice architecture with Fastify, including dependency injection, health checks, metrics endpoints, and graceful shutdown handling.",
"scenario": "Building a production-ready microservice for a distributed system"
}
],
"output_examples": [
{
"input": "How do I set up rate limiting for my Express API?",
"output": "Use express-rate-limit with Redis for distributed rate limiting. Configure separate limits for general API endpoints and authentication endpoints. Example: apiLimiter allows 100 requests per 15 minutes, while authLimiter allows 5 requests per 15 minutes with stricter enforcement."
},
{
"input": "What is the proper way to handle errors in Express?",
"output": "Create custom error classes extending Error for different error types (ValidationError, NotFoundError, UnauthorizedError). Implement a global error handler middleware that logs errors and returns appropriate HTTP status codes without exposing internal details in production."
}
],
"best_practices": [
"Always use TypeScript for type safety and better IDE support",
"Validate all user input with libraries like Zod before processing",
"Use environment variables for configuration and never commit secrets to version control"
],
"anti_patterns": [
"Using wildcard CORS origins in production environments",
"Storing sensitive data like passwords or tokens in plain text",
"Blocking the event loop with synchronous operations or complex calculations"
],
"faq": [
{
"question": "Should I use Express or Fastify for my project?",
"answer": "Express has a larger ecosystem and is well-established. Fastify offers better performance with built-in schema validation. Choose Express for maximum compatibility or Fastify for high-throughput APIs."
},
{
"question": "How do I handle database migrations in Node.js?",
"answer": "Use migration tools like Knex, Prisma, or typeorm. Define migrations as version-controlled files that can be applied or rolled back. Run migrations during deployment before starting the application."
},
{
"question": "What is the recommended project structure for Node.js APIs?",
"answer": "Use layered architecture: controllers handle HTTP requests, services contain business logic, repositories manage data access. Keep configuration, middleware, types, and utilities in separate directories."
},
{
"question": "How should I implement authentication in Node.js?",
"answer": "Use JWT for stateless authentication with short-lived access tokens and longer-lived refresh tokens. Hash passwords with bcrypt or argon2. Store secrets in environment variables and rotate them regularly."
},
{
"question": "What logging approach should I use in production?",
"answer": "Use structured logging with Pino or Winston. Include correlation IDs for tracing requests across services. Log to stdout and aggregate logs with tools like ELK stack or cloud logging services."
},
{
"question": "How do I ensure my Node.js API can handle high traffic?",
"answer": "Implement connection pooling for databases, add caching with Redis, use compression for responses, enable clustering to use all CPU cores, and implement proper rate limiting to prevent abuse."
}
]
},
"file_structure": [
{
"name": "resources",
"type": "dir",
"path": "resources",
"children": [
{
"name": "implementation-playbook.md",
"type": "file",
"path": "resources/implementation-playbook.md",
"lines": 1020
}
]
},
{
"name": "SKILL.md",
"type": "file",
"path": "SKILL.md",
"lines": 38
}
]
}
Related skills
FAQ
Which frameworks does it cover?
It targets Express and Fastify for building REST APIs, GraphQL servers, and microservices.
Does it cover authentication?
Yes, it covers implementing authentication and authorization along with middleware and error handling.