Skip to main content

javascript-strict

JavaScript (Node.js) strictness, clean code, and security rules. Use when writing, reviewing, or refactoring plain JavaScript (non-TypeScript) Node.js code. Covers const-first variable declarations, async/await patterns, class vs function patterns, JSDoc documentation, error handling, hot-path performance, CommonJS module patterns, and vulnerability prevention. Derived from production Node.js services.

Source facts

Repository
0xMassi/claude-skills
Last source activity
April 28, 2026 at 15:15
Detected SKILL.md language
English
Stars
8
Forks
2

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
javascript-strict
description
JavaScript (Node.js) strictness, clean code, and security rules. Use when writing, reviewing, or refactoring plain JavaScript (non-TypeScript) Node.js code. Covers const-first variable declarations, async/await patterns, class vs function patterns, JSDoc documentation, error handling, hot-path performance, CommonJS module patterns, and vulnerability prevention. Derived from production Node.js services.
# JavaScript Strict Standard Rules extracted from production Node.js services (non-TypeScript). ## CRITICAL: Variable Declarations ### JS-01: const by default, let when necessary, never var ```javascript // BAD var count = 0; var items = []; // GOOD const VALID_MODES = ['bypass', 'browser', 'capsolver']; // Never changes let activeCount = 0; // Reassigned in loop let currentDelay = baseDelay; // Mutated by logic ``` No `var` anywhere. ### JS-02: Destructure at declaration ```javascript // BAD const name = config.name; const port = config.port; const mode = config.mode; // GOOD const { name, port, mode } = config; // GOOD: with defaults const { mode = 'both', delay = 1000 } = options; ``` ## CRITICAL: Error Handling ### JS-03: Never catch and swallow errors ```javascript // BAD try { await save(); } catch (e) {} // BAD: logs but no recovery try { await save(); } catch (e) { console.log(e); } // GOOD: context + action try { await save(); } catch (err) { console.error(`[Monitor] ${this.monitorId} Save failed:`, err.message); await this.notifyError('save_failure', err.message); // Decide: retry, skip, or throw } ``` ### JS-04: Prefix error logs with context ```javascript // BAD console.error(err.message); // GOOD console.error(`[Monitor] ${this.monitorId} Error:`, err.message); console.error(`[TokenBank] ${this.baseHost} Persist failed:`, err.message); console.warn(`[DEPRECATED] MONITOR_BYPASS is deprecated, use TMPT_MODE`); ``` Format: `[Module] ${identifier} Action: message` ### JS-05: Avoid recursive retry without limits ```javascript // BAD: infinite recursion on persistent failure async getTmpt() { try { const token = await this.tmptBank.getTmpt(); if (!token) { await sleep(1000); return this.getTmpt(); } return token; } catch { await sleep(1000); return this.getTmpt(); // STACK OVERFLOW on persistent failure } } // GOOD: bounded retries async getTmpt(retries = 10) { for (let i = 0; i < retries; i++) { try { const token = await this.tmptBank.getTmpt(); if (token) return token; } catch (err) { console.error(`[Monitor] getTmpt attempt ${i + 1}/${retries}:`, err.message); } await sleep(1000 * Math.min(i + 1, 5)); // Backoff } throw new Error(`Failed to get TMPT after ${retries} attempts`); } ``` ## CRITICAL: Async Patterns ### JS-06: async/await over raw Promises ```javascript // BAD function fetchData() { return fetch(url).then(r => r.json()).then(data => process(data)).catch(handleError); } // GOOD async function fetchData() { const response = await fetch(url); const data = await response.json(); return process(data); } ``` ### JS-07: Promise.race for timeouts ```javascript function withTimeout(promise, ms, message = 'Timeout') { let timeoutId; const timeoutPromise = new Promise((_, reject) => { timeoutId = setTimeout(() => reject(new Error(message)), ms); }); return Promise.race([promise, timeoutPromise]) .finally(() => clearTimeout(timeoutId)); // ALWAYS clean up } // Usage const data = await withTimeout(fetch(url), 5000, 'Request timed out'); ``` Always `.finally()` to clear the timeout: prevents dangling timers. ### JS-08: Async file I/O only ```javascript // BAD: blocks event loop 5-50ms fs.writeFileSync(path, JSON.stringify(data, null, 2)); // GOOD await fs.promises.writeFile(path, JSON.stringify(data, null, 2)); // BETTER: skip if unchanged const json = JSON.stringify(data, null, 2); const hash = crypto.createHash('md5').update(json).digest('hex'); if (hash !== this._lastHash) { await fs.promises.writeFile(path, json); this._lastHash = hash; } ``` ## HIGH: Module Patterns ### JS-09: CommonJS with clear exports ```javascript // Single class export class Monitor { ... } module.exports = Monitor; // Named function exports module.exports = { addMonitor: async (data) => { ... }, getMonitor: async (id) => { ... }, updateMonitor: async (id, updates) => { ... }, }; // Utility exports const { sleep, withTimeout, shouldRun } = require('./utils'); module.exports = { sleep, withTimeout, shouldRun }; ``` ### JS-10: No circular dependencies If A requires B and B requires A, extract shared logic into C. ## HIGH: Class Patterns ### JS-11: Classes for stateful objects, functions for utilities ```javascript // GOOD: class for stateful service class Monitor { constructor(monitorData, tmptBank, mode = 'both') { this.monitorId = monitorData.id; this.tmptBank = tmptBank; this.mode = mode; this.stopped = false; this.delay = 100; this.notifiedListings = new Set(); // Use Set, not Array } async start() { ... } async stop() { this.stopped = true; } } // GOOD: plain functions for stateless utilities function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function formatProxy(line) { const [host, port, user, pass] = line.split(':'); return `http://${user}:${pass}@${host}:${port}`; } ``` ## HIGH: Documentation (JSDoc) ### JS-12: JSDoc for all public methods ```javascript /** * Makes an HTTP request with TMPT error handling and retry logic. * @param {Object} config - Request configuration * @param {string} config.url - Target URL * @param {string} [config.method='GET'] - HTTP method * @param {Object} [config.headers] - Additional headers * @param {number} [config.timeout=5000] - Timeout in milliseconds * @returns {Promise<Object>} Response object with data and status * @throws {Error} If request fails after retries */ async makeRequest(config) { ... } ``` Essential for non-TypeScript codebases: provides IDE autocomplete and documentation. ## MEDIUM: Performance Rules ### JS-13: Set for membership, Map for lookups ```javascript // BAD: O(n) per check const newIds = currentIds.filter(x => !savedIds.includes(x)); // GOOD: O(1) per check const savedSet = new Set(savedIds); const newIds = currentIds.filter(x => !savedSet.has(x)); ``` ### JS-14: Single-pass algorithms in hot paths ```javascript // BAD: 3 passes, 3 arrays const available = tokens.filter(t => !t.expired); available.sort((a, b) => a.lastUsed - b.lastUsed); const best = available[0]; // GOOD: 1 pass, 0 arrays let best = null; for (const t of tokens) { if (t.expired) continue; if (!best || t.lastUsed < best.lastUsed) best = t; } ``` ### JS-15: Cache expensive computations ```javascript // BAD: regex + split every call function getProxy() { const proxies = source.split(/\r?\n/); return proxies[Math.floor(Math.random() * proxies.length)].split(':'); } // GOOD: parse once class ProxyPool { constructor(source) { this.urls = source.split(/\r?\n/).filter(Boolean).map(formatProxy); } random() { return this.urls[Math.floor(Math.random() * this.urls.length)]; } } ``` ### JS-16: Index Maps for frequent lookups ```javascript // BAD: O(n) find per lookup function findToken(value) { return this.tokens.find(t => t.value === value); } // GOOD: O(1) Map lookup this.tokenIndex = new Map(tokens.map(t => [t.value, t])); function findToken(value) { return this.tokenIndex.get(value); } ``` ## Security Rules ### JS-17: Never eval() or Function() ```javascript // BAD: code injection eval(userInput); new Function(userInput)(); // GOOD: use safe alternatives JSON.parse(jsonString); ``` ### JS-18: Never innerHTML with user data ```javascript // BAD: XSS element.innerHTML = `<p>${userInput}</p>`; // GOOD element.textContent = userInput; ``` ### JS-19: Environment variables for secrets ```javascript // BAD: in source code const API_KEY = 'sk-abc123...'; // GOOD require('dotenv').config(); const API_KEY = process.env.API_KEY; if (!API_KEY) throw new Error('API_KEY required'); ``` ### JS-20: Mask secrets in logs ```javascript // BAD console.log(`Token: ${token}`); // GOOD console.log(`Token: ${token.slice(0, 8)}...`); ``` ### JS-21: Be cautious with NODE_TLS_REJECT_UNAUTHORIZED ```javascript // DANGER: disables SSL verification globally process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; // BETTER: per-request agent with custom CA const agent = new https.Agent({ rejectUnauthorized: false }); // Only use for proxy connections, never for production APIs ``` ### JS-22: AbortController for cancellable fetch and timeouts ```javascript // BAD: no way to cancel; the fetch leaks if the caller goes away const data = await fetch(url).then(r => r.json()); // GOOD: timeout + caller-driven cancellation async function fetchJSON(url, { signal, timeoutMs = 5000 } = {}) { const ctrl = new AbortController(); const timer = setTimeout(() => ctrl.abort(new Error('timeout')), timeoutMs); signal?.addEventListener('abort', () => ctrl.abort(signal.reason)); try { const res = await fetch(url, { signal: ctrl.signal }); return await res.json(); } finally { clearTimeout(timer); } } ``` Replaces the `Promise.race` timeout pattern in modern Node. ### JS-23: `crypto.randomBytes` for tokens, never `Math.random` ```javascript // BAD: predictable, seedable, not for security const token = Math.random().toString(36).slice(2); // GOOD: cryptographically random const { randomBytes } = require('node:crypto'); const token = randomBytes(32).toString('hex'); ``` Same rule for session IDs, password reset tokens, nonces, and salts. ## Runtime Targets - **Node.js 24 LTS "Krypton"** is the current Active LTS, supported through April 2028. Latest patch line is 24.15.x. New projects target Node 24. - **Release schedule change** (announced Oct 2026 cycle): one major release per year (April), every release becomes LTS after the October promotion. Plan upgrades around April + October windows. - **Native TypeScript stripping** is unflagged default since Node 23.6, available throughout 24.x. `--experimental-transform-types` still required for enums/namespaces (which `erasableSyntaxOnly` in TS bans anyway). ### JS-24a: Use stdlib over third-party where Node has shipped equivalents | Replace | With (Node 22+) | |---|---|
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub