.claude/skills/node/SKILL.md
Node.js LTS runtime and server-side JavaScript patterns for INVOOPAY backend. Use when: working with backend services, async operations, crypto, Buffer handling, or Node.js APIs.
npx skillsauth add kaxuna1/ecomsite nodeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Node.js 20 LTS runtime powering Express + TypeScript backend. Uses ES modules ("type": "module") with tsx for development. PostgreSQL via pg with connection pooling. Sharp for image processing.
// backend/src/server.ts - Entry point
import app from './app.js'; // .js extension required for ESM
import { env } from './config/env.js';
app.listen(env.port, () => {
console.log(`Backend listening on port ${env.port}`);
});
// backend/src/config/env.ts - Validated env with defaults
import dotenv from 'dotenv';
dotenv.config();
const required = (value: string | undefined, fallback?: string) => {
if (value) return value;
if (fallback !== undefined) return fallback;
throw new Error('Missing required environment variable');
};
export const env = {
port: Number(process.env.PORT ?? 4000),
dbHost: process.env.DB_HOST ?? 'localhost',
jwtSecret: required(process.env.JWT_SECRET, 'dev-only-secret'),
nodeEnv: process.env.NODE_ENV ?? 'development',
};
// backend/src/db/client.ts
import pg from 'pg';
const { Pool } = pg;
export const pool = new Pool({
host: env.dbHost,
max: 20, // Max connections
idleTimeoutMillis: 30000, // Close idle after 30s
connectionTimeoutMillis: 2000,
});
pool.on('error', (err) => {
console.error('Unexpected error on idle client', err);
process.exit(-1); // Crash on pool errors
});
| Concept | Usage | Example |
|---------|-------|---------|
| ESM imports | Always use .js extension | import { x } from './mod.js' |
| __dirname | Use import.meta.url | path.dirname(fileURLToPath(import.meta.url)) |
| Async/await | All I/O operations | await pool.query(...) |
| Buffer | Binary data handling | Buffer.from(data, 'hex') |
| crypto | Encryption/hashing | crypto.randomBytes(32) |
export const productService = {
async get(id: number, language: string = 'en') {
const result = await pool.query(
'SELECT * FROM products WHERE id = $1', [id]
);
if (!result.rows[0]) return null;
return mapProduct(result.rows[0]);
}
};
const client = await pool.connect();
try {
await client.query('BEGIN');
await client.query('INSERT ...', [...]);
await client.query('UPDATE ...', [...]);
await client.query('COMMIT');
} catch (error) {
await client.query('ROLLBACK');
throw error;
} finally {
client.release(); // Always release!
}
For Express routes and middleware, see the express skill. For database queries, see the postgresql skill. For TypeScript patterns, see the typescript skill.
tools
Zustand lightweight state management with persistence and middleware. Use when: managing client-side state (cart, auth, UI preferences), replacing React Context with simpler API, accessing state outside React components, implementing localStorage persistence
development
Zod schema validation and TypeScript integration for runtime type safety. Use when: Validating API payloads, form inputs, environment variables, or any external data boundaries where TypeScript types alone cannot guarantee safety.
tools
Configures Vite 5.x build tool, dev server, and frontend asset optimization for the Luxia e-commerce platform. Use when: configuring builds, adding environment variables, optimizing bundle size, setting up testing, debugging HMR issues, or adding Vite plugins.
development
Enforces strict TypeScript types across frontend and backend codebases. Use when: Writing new services, DTOs, interfaces, type guards, debugging type errors, or ensuring type safety at API boundaries.