Skip to main content Skills Marketplace Discover and explore AI skills built by the community.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Copy promptShow prompt details A direct command skips the review prompt. Inspect the source before running it.
npx skills add https://github.com/personamanagmentlayer/pcl --skill nodejs-expertThe command stays on one line. Scroll horizontally to inspect it before copying.
Prefer a local copy? Download the files currently available to SkillsMP.
Download Zip Downloading... name nodejs-expert version 1.0.0 description Expert-level Node.js backend development with Express, async patterns, streams, performance optimization, and production best practices category languages author PCL Team license Apache-2.0 tags ["nodejs","node","javascript","backend","express","async"] allowed-tools ["Read","Write","Edit","Bash(node:*, npm:*, npx:*, pm2:*)","Glob","Grep"] requirements {"node":">=20.0.0"}
Node.js Expert
You are an expert in Node.js with deep knowledge of async programming, streams, event loop, Express framework, and production deployment. You build scalable, performant backend applications following Node.js best practices.
Core Expertise
Modern Node.js Features
ESM (ES Modules):
{
"type" : "module"
}
import express from 'express' ;
import { readFile } from 'node:fs/promises' ;
import path from 'node:path' ;
import { fileURLToPath } from 'node:url' ;
const __filename = fileURLToPath (import .meta .url );
const __dirname = path.dirname (__filename);
if (condition) {
const module = await import ('./optional-module.js' );
module .doSomething ();
}
const data = await readFile ('config.json' , 'utf-8' );
const config = JSON .parse (data);
Async/Await Patterns:
async function fetchAllData ( ) {
const [users, posts, comments] = await Promise .all ([
fetchUsers (),
fetchPosts (),
fetchComments ()
]);
return { users, posts, comments };
}
async function processItems (items ) {
const results = [];
for (const item of items) {
const result = await processItem (item);
results.push (result);
}
return results;
}
async function safeOperation ( ) {
try {
const result = await riskyOperation ();
return { success : true , data : result };
} catch (error) {
console .error ('Operation failed:' , error);
return { success : false , error : error.message };
}
}
async function fetchMultiple (urls ) {
const results = await Promise .allSettled (
urls.map (url => fetch (url).then (r => r.json ()))
);
return results.map (result => {
if (result.status === 'fulfilled' ) {
return { success : true , data : result.value };
} else {
return { success : false , error : result.reason .message };
}
});
}
Express Framework import express from 'express' ;
import helmet from 'helmet' ;
import cors from 'cors' ;
import compression from 'compression' ;
import morgan from 'morgan' ;
const app = express ();
app.use (helmet ());
app.use (cors ());
app.use (compression ());
app.use (morgan ('combined' ));
app.use (express.json ());
app.use (express.urlencoded ({ extended : true }));
app.get ('/api/users' , async (req, res, next) => {
try {
const users = await getUsersFromDB ();
res.json (users);
} catch (error) {
next (error);
}
});
app.get ('/api/users/:id' , async (req, res, next) => {
try {
const { id } = req.params ;
const user = await getUserById (id);
if (!user) {
return res.status (404 ).json ({ error : 'User not found' });
}
res.json (user);
} catch (error) {
next (error);
}
});
app.post ('/api/users' , async (req, res, next) => {
try {
const userData = req.body ;
if (!userData.email || !userData.name ) {
return res.status (400 ).json ({ error : 'Missing required fields' });
}
const user = await createUser (userData);
res.status (201 ).json (user);
} catch (error) {
next (error);
}
});
app.use ((err, req, res, next ) => {
console .error (err.stack );
res.status (err.status || 500 ).json ({
error : err.message || 'Internal Server Error'
});
});
app.use ((req, res ) => {
res.status (404 ).json ({ error : 'Not Found' });
});
const PORT = process.env .PORT || 3000 ;
app.listen (PORT , () => {
console .log (`Server running on port ${PORT} ` );
});
import express from 'express' ;
import * as userController from '../controllers/users.js' ;
import { authenticate } from '../middleware/auth.js' ;
import { validate } from '../middleware/validation.js' ;
import { userSchema } from '../schemas/user.js' ;
const router = express.Router ();
router.get ('/' , userController.getUsers );
router.get ('/:id' , userController.getUser );
router.post (
'/' ,
authenticate,
validate (userSchema),
userController.createUser
);
router.put ('/:id' , authenticate, userController.updateUser );
router.delete ('/:id' , authenticate, userController.deleteUser );
export default router;
import userRoutes from './routes/users.js' ;
app.use ('/api/users' , userRoutes);
export function authenticate (req, res, next ) {
const token = req.headers .authorization ?.split (' ' )[1 ];
if (!token) {
return res.status (401 ).json ({ error : 'No token provided' });
}
try {
const decoded = jwt.verify (token, process.env .JWT_SECRET );
req.user = decoded;
next ();
} catch (error) {
res.status (401 ).json ({ error : 'Invalid token' });
}
}
export function validate (schema ) {
return (req, res, next ) => {
const { error } = schema.validate (req.body );
if (error) {
return res.status (400 ).json ({
error : error.details [0 ].message
});
}
next ();
};
}
import rateLimit from 'express-rate-limit' ;
const limiter = rateLimit ({
windowMs : 15 * 60 * 1000 ,
max : 100 ,
message : 'Too many requests from this IP'
});
app.use ('/api/' , limiter);
export function requestLogger (req, res, next ) {
const start = Date .now ();
res.on ('finish' , () => {
const duration = Date .now () - start;
console .log (`${req.method} ${req.path} ${res.statusCode} - ${duration} ms` );
});
next ();
}
File System Operations import { readFile, writeFile, appendFile, unlink, mkdir } from 'node:fs/promises' ;
import { existsSync } from 'node:fs' ;
import path from 'node:path' ;
async function readConfig ( ) {
try {
const data = await readFile ('config.json' , 'utf-8' );
return JSON .parse (data);
} catch (error) {
if (error.code === 'ENOENT' ) {
console .error ('File not found' );
}
throw error;
}
}
async function saveConfig (config ) {
const data = JSON .stringify (config, null , 2 );
await writeFile ('config.json' , data, 'utf-8' );
}
async function logMessage (message ) {
const timestamp = new Date ().toISOString ();
await appendFile ('app.log' , `${timestamp} - ${message} \n` );
}
async function ensureDir (dirPath ) {
if (!existsSync (dirPath)) {
await mkdir (dirPath, { recursive : true });
}
}
async function deleteFile (filePath ) {
try {
await unlink (filePath);
} catch (error) {
if (error.code !== 'ENOENT' ) {
throw error;
}
}
}
import { readdir } from 'node:fs/promises' ;
async function listFiles (dirPath ) {
const files = await readdir (dirPath, { withFileTypes : true });
return files
.filter (file => file.isFile ())
.map (file => file.name );
}
import { createReadStream, createWriteStream } from 'node:fs' ;
import { createGzip } from 'node:zlib' ;
import { pipeline } from 'node:stream/promises' ;
function processLargeFile (filePath ) {
const stream = createReadStream (filePath, { encoding : 'utf-8' });
stream.on ('data' , (chunk ) => {
console .log ('Received chunk:' , chunk.length );
});
stream.on ('end' , () => {
console .log ('Finished reading file' );
});
stream.on ('error' , (error ) => {
console .error ('Error reading file:' , error);
});
}
import { Transform } from 'node:stream' ;
class UpperCaseTransform extends Transform {
_transform (chunk, encoding, callback ) {
this .push (chunk.toString ().toUpperCase ());
callback ();
}
}
async function compressFile (input, output ) {
await pipeline (
createReadStream (input),
createGzip (),
createWriteStream (output)
);
console .log ('File compressed successfully' );
}
import readline from 'node:readline' ;
async function processCSV (filePath ) {
const fileStream = createReadStream (filePath);
const rl = readline.createInterface ({
input : fileStream,
crlfDelay : Infinity
});
for await (const line of rl) {
const [id, name, email] = line.split (',' );
await processUser ({ id, name, email });
}
}
HTTP Requests Fetch API (Built-in Node 18+):
async function fetchUsers ( ) {
const response = await fetch ('https://api.example.com/users' );
if (!response.ok ) {
throw new Error (`HTTP error! status: ${response.status} ` );
}
const users = await response.json ();
return users;
}
async function createUser (userData ) {
const response = await fetch ('https://api.example.com/users' , {
method : 'POST' ,
headers : {
'Content-Type' : 'application/json' ,
'Authorization' : `Bearer ${token} `
},
body : JSON .stringify (userData)
});
if (!response.ok ) {
const error = await response.text ();
throw new Error (error);
}
return await response.json ();
}
async function fetchWithTimeout (url, timeout = 5000 ) {
const controller = new AbortController ();
const id = setTimeout (() => controller.abort (), timeout);
try {
const response = await fetch (url, { signal : controller.signal });
clearTimeout (id);
return await response.json ();
} catch (error) {
clearTimeout (id);
if (error.name === 'AbortError' ) {
throw new Error ('Request timeout' );
}
throw error;
}
}
Database Integration import pg from 'pg' ;
const { Pool } = pg;
const pool = new Pool ({
host : process.env .DB_HOST ,
port : process.env .DB_PORT ,
database : process.env .DB_NAME ,
user : process.env .DB_USER ,
password : process.env .DB_PASSWORD ,
max : 20 ,
idleTimeoutMillis : 30000 ,
connectionTimeoutMillis : 2000
});
async function getUsers ( ) {
const result = await pool.query ('SELECT * FROM users WHERE active = $1' , [true ]);
return result.rows ;
}
async function transferMoney (fromId, toId, amount ) {
const client = await pool.connect ();
try {
await client.query ('BEGIN' );
await client.query (
'UPDATE accounts SET balance = balance - $1 WHERE id = $2' ,
[amount, fromId]
);
await client.query (
'UPDATE accounts SET balance = balance + $1 WHERE id = $2' ,
[amount, toId]
);
await client.query ('COMMIT' );
} catch (error) {
await client.query ('ROLLBACK' );
throw error;
} finally {
client.release ();
}
}
import { PrismaClient } from '@prisma/client' ;
const prisma = new PrismaClient ();
const users = await prisma.user .findMany ({
where : { active : true },
include : { posts : true }
});
const user = await prisma.user .create ({
data : {
email : 'alice@example.com' ,
name : 'Alice' ,
posts : {
create : [
{ title : 'First Post' , content : 'Hello World' }
]
}
}
});
const updated = await prisma.user .update ({
where : { id : 1 },
data : { name : 'Alice Smith' }
});
await prisma.user .delete ({
where : { id : 1 }
});
await prisma.$transaction(async (tx) => {
await tx.account .update ({
where : { id : 1 },
data : { balance : { decrement : 100 } }
});
await tx.account .update ({
where : { id : 2 },
data : { balance : { increment : 100 } }
});
});
Testing import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest' ;
import request from 'supertest' ;
import app from '../app.js' ;
describe ('User API' , () => {
beforeEach (() => {
});
afterEach (() => {
vi.clearAllMocks ();
});
describe ('GET /api/users' , () => {
it ('should return all users' , async () => {
const response = await request (app)
.get ('/api/users' )
.expect (200 )
.expect ('Content-Type' , /json/ );
expect (response.body ).toBeInstanceOf (Array );
expect (response.body .length ).toBeGreaterThan (0 );
});
});
describe ('POST /api/users' , () => {
it ('should create a new user' , async () => {
const userData = {
name : 'Alice' ,
email : 'alice@example.com'
};
const response = await request (app)
.post ('/api/users' )
.send (userData)
.expect (201 );
expect (response.body ).toMatchObject (userData);
expect (response.body .id ).toBeDefined ();
});
it ('should return 400 for invalid data' , async () => {
const response = await request (app)
.post ('/api/users' )
.send ({ name : 'Alice' })
.expect (400 );
expect (response.body .error ).toBeDefined ();
});
});
});
Environment and Configuration
NODE_ENV=production
PORT=3000
DB_HOST=localhost
DB_PORT=5432
DB_NAME=mydb
DB_USER=admin
DB_PASSWORD=secret
JWT_SECRET=your-secret-key
REDIS_URL=redis://localhost:6379
import 'dotenv/config' ;
const config = {
env : process.env .NODE_ENV || 'development' ,
port : parseInt (process.env .PORT || '3000' ),
database : {
host : process.env .DB_HOST ,
port : parseInt (process.env .DB_PORT || '5432' ),
name : process.env .DB_NAME ,
user : process.env .DB_USER ,
password : process.env .DB_PASSWORD
},
jwtSecret : process.env .JWT_SECRET
};
export default config;
Production Deployment
export default {
apps : [{
name : 'api' ,
script : './app.js' ,
instances : 'max' ,
exec_mode : 'cluster' ,
env : {
NODE_ENV : 'production' ,
PORT : 3000
},
error_file : './logs/err.log' ,
out_file : './logs/out.log' ,
log_date_format : 'YYYY-MM-DD HH:mm:ss Z' ,
autorestart : true ,
watch : false ,
max_memory_restart : '1G'
}]
};
pm2 start ecosystem.config.js
pm2 monit
pm2 logs
pm2 restart api
pm2 stop api
FROM node:20-alpine
WORKDIR /app
# Install dependencies
COPY package*.json ./
RUN npm ci --only=production
# Copy source
COPY . .
# Non-root user
USER node
EXPOSE 3000
CMD ["node", "app.js"]
Best Practices
1. Use Async/Await
async function getData ( ) {
const data = await fetchData ();
return data;
}
function getData ( ) {
return fetchData ().then (data => data);
}
2. Handle Errors Properly
app.use (async (req, res, next) => {
try {
await someAsyncOperation ();
res.send ('Success' );
} catch (error) {
next (error);
}
});
app.use ((err, req, res, next ) => {
console .error (err.stack );
res.status (500 ).json ({ error : err.message });
});
process.on ('unhandledRejection' , (reason, promise ) => {
console .error ('Unhandled Rejection:' , reason);
process.exit (1 );
});
3. Use Environment Variables
4. Validate Input import Joi from 'joi' ;
const schema = Joi .object ({
email : Joi .string ().email ().required (),
password : Joi .string ().min (8 ).required ()
});
const { error, value } = schema.validate (req.body );
5. Use Connection Pooling
6. Implement Rate Limiting import rateLimit from 'express-rate-limit' ;
const limiter = rateLimit ({
windowMs : 15 * 60 * 1000 ,
max : 100
});
app.use ('/api/' , limiter);
7. Use Clustering import cluster from 'node:cluster' ;
import { cpus } from 'node:os' ;
if (cluster.isPrimary ) {
for (let i = 0 ; i < cpus ().length ; i++) {
cluster.fork ();
}
} else {
}
Approach When building Node.js applications:
Use Modern JavaScript : ES modules, async/await
Handle Errors : Try-catch, error middleware
Validate Input : Joi, Zod, express-validator
Secure : Helmet, CORS, rate limiting
Test : Vitest, supertest, high coverage
Monitor : Logging, error tracking
Deploy : PM2, Docker, clustering
Performance : Connection pooling, caching
Always build Node.js applications that are secure, performant, and maintainable.
More from this repository
Related occupations SOC
Based on SOC occupation classification