Writes, debugs, and refactors JavaScript code using modern ES2023+ features, async/await patterns, ESM module systems, and Node.js APIs. Use when building vanilla JavaScript applications, implementing Promise-based async flows, optimising browser or Node.js performance, working with Web Workers or Fetch API, or reviewing .js/.mjs/.cjs files for correctness and best practices.
git clone https://github.com/Jeffallan/claude-skills.git--- name: javascript-pro description: Writes, debugs, and refactors JavaScript code using modern ES2023+ features, async/await patterns, ESM module systems, and Node.js APIs. Use when building vanilla JavaScript applications, implementing Promise-based async flows, optimising browser or Node.js performance, working with Web Workers or Fetch API, or reviewing .js/.mjs/.cjs files for correctness and best practices. license: MIT metadata: author: https://github.com/Jeffallan version: "1.1.0" domain: language triggers: JavaScript, ES2023, async await, Node.js, vanilla JavaScript, Web Workers, Fetch API, browser API, module system role: specialist scope: implementation output-format: code related-skills: fullstack-guardian --- # JavaScript Pro ## When to Use This Skill - Building vanilla JavaScript applications - Implementing async/await patterns and Promise handling - Working with modern module systems (ESM/CJS) - Optimizing browser performance and memory usage - Developing Node.js backend services - Implementing Web Workers, Service Workers, or browser APIs ## Core Workflow 1. **Analyze requirements** — Review `package.json`, module system, Node version, browser targets; confirm `.js`/`.mjs`/`.cjs` conventions 2. **Design architecture** — Plan modules, async flows, and error handling strategies 3. **Implement** — Write ES2023+ code with proper patterns and optimisations 4. **Validate** — Run linter (`eslint --fix`); if linter fails, fix all reported issues and re-run before proceeding. Check for memory leaks with DevTools or `--inspect`, verify bundle size; if leaks are found, resolve them before continuing 5. **Test** — Write comprehensive tests with Jest achieving 85%+ coverage; if coverage falls short, add missing cases and re-run. Confirm no unhandled Promise rejections ## Reference Guide Load detailed guidance based on context: | Topic | Reference | Load When | |-------|-----------|-----------| | Modern Syntax | `references/modern-syntax.md` | ES2023+ features, optional chaining, private fields | | Async Patterns | `references/async-patterns.md` | Promises, async/await, error handling, event loop | | Modules | `references/modules.md` | ESM vs CJS, dynamic imports, package.json exports | | Browser APIs | `references/browser-apis.md` | Fetch, Web Workers, Storage, IntersectionObserver | | Node Essentials | `references/node-essentials.md` | fs/promises, streams, EventEmitter, worker threads | ## Constraints ### MUST DO - Use ES2023+ features exclusively - Use `X | null` or `X | undefined` patterns - Use optional chaining (`?.`) and nullish coalescing (`??`) - Use async/await for all asynchronous operations - Use ESM (`import`/`export`) for new projects - Implement proper error handling with try/catch - Add JSDoc comments for complex functions - Follow functional programming principles ### MUST NOT DO - Use `var` (always use `const` or `let`) - Use callback-based patterns (prefer Promises) - Mix CommonJS and ESM in the same module - Ignore memory leaks or performance issues - Skip error handling in async functions - Use synchronous I/O in Node.js - Mutate function parameters - Create blocking operations in the browser ## Key Patterns with Examples ### Async/Await Error Handling ```js // ✅ Correct — always handle async errors explicitly async function fetchUser(id) { try { const response = await fetch(`/api/users/${id}`); if (!response.ok) throw new Error(`HTTP ${response.status}`); return await response.json(); } catch (err) { console.error("fetchUser failed:", err); return null; } } // ❌ Incorrect — unhandled rejection, no null guard async function fetchUser(id) { const response = await fetch(`/api/users/${id}`); return response.json(); } ``` ### Optional Chaining & Nullish Coalescing ```js // ✅ Correct const city = user?.address?.city ?? "Unknown"; // ❌ Incorrect — throws if address is undefined const city = user.address.city || "Unknown"; ``` ### ESM Module Structure ```js // ✅ Correct — named exports, no default-only exports for libraries // utils/math.mjs export const add = (a, b) => a + b; export const multiply = (a, b) => a * b; // consumer.mjs import { add } from "./utils/math.mjs"; // ❌ Incorrect — mixing require() with ESM const { add } = require("./utils/math.mjs"); ``` ### Avoid var / Prefer const ```js // ✅ Correct const MAX_RETRIES = 3; let attempts = 0; // ❌ Incorrect var MAX_RETRIES = 3; var attempts = 0; ``` ## Output Templates When implementing JavaScript features, provide: 1. Module file with clean exports 2. Test file with comprehensive coverage 3. JSDoc documentation for public APIs 4. Brief explanation of patterns used [Documentation](https://jeffallan.github.io/claude-skills/skills/language/javascript-pro/)
[{"step":"Define your requirements precisely. Specify the exact functionality, input/output types, error conditions, and performance constraints. Include any external APIs or libraries you must use.","tip":"Use JSDoc comments to document expected types and behaviors before writing code. This makes the AI's job easier and ensures you get type-safe output."},{"step":"Paste the prompt template into your AI tool, replacing [PLACEHOLDERS] with your specific needs. For complex projects, break it into smaller modules first.","tip":"For Node.js projects, specify the Node.js version (e.g., 'Node.js 20+') to ensure compatibility with modern APIs like fetch() or Web Workers."},{"step":"Review the generated code for correctness and security. Check for: proper error handling, input validation, memory leaks (e.g., event listeners), and API rate limits.","tip":"Use ESLint with modern configs (e.g., 'eslint-config-airbnb' or 'eslint-config-standard-with-typescript') to catch common issues automatically."},{"step":"Add unit tests using the provided stubs. Extend the test coverage to include edge cases like network failures, invalid inputs, and race conditions.","tip":"For browser APIs like localStorage, mock them in tests using Jest's environment configuration or tools like jsdom."},{"step":"Optimize performance. Profile the code using Chrome DevTools or Node.js's built-in profiler. Look for bottlenecks in async operations, memory usage, or DOM manipulations.","tip":"For heavy computations, consider Web Workers or memoization. For I/O-bound tasks, use streams or batch processing to reduce memory pressure."}]
No install command available. Check the GitHub repository for manual installation instructions.
git clone https://github.com/Jeffallan/claude-skills/tree/main/skills/javascript-proCopy the install command above and run it in your terminal.
Launch Claude Code, Cursor, or your preferred AI coding agent.
Use the prompt template or examples below to test the skill.
Adapt the skill to your specific use case and workflow.
Write a production-ready JavaScript module that implements [FUNCTIONALITY] using modern ES2023+ syntax, ESM modules, and async/await patterns. Include: 1) Input validation with TypeScript-like JSDoc annotations, 2) Error handling for network/IO operations, 3) Performance optimizations like debouncing or memoization where applicable, 4) JSDoc comments for all public functions, and 5) Unit test stubs using Jest. Use [LANGUAGE_LEVEL] (e.g., 'ES2023+', 'Node.js 20+'). Example: 'Write a module that fetches GitHub user data via the REST API, caches results for 5 minutes using localStorage, and handles rate limiting with exponential backoff.'
```javascript
// File: githubUserFetcher.mjs
/**
* Fetches GitHub user data with caching and rate limiting
* @param {string} username - GitHub username
* @param {number} [cacheTTL=300000] - Cache duration in ms (default: 5 minutes)
* @returns {Promise<{login: string, name: string, avatar_url: string, public_repos: number}>} User data
* @throws {Error} For invalid usernames or API errors
*/
export async function fetchGitHubUser(username, cacheTTL = 300000) {
if (typeof username !== 'string' || !username.trim()) {
throw new Error('Username must be a non-empty string');
}
// Check cache first
const cacheKey = `github_user_${username}`;
const cached = localStorage.getItem(cacheKey);
if (cached) {
const { data, timestamp } = JSON.parse(cached);
if (Date.now() - timestamp < cacheTTL) {
return data;
}
}
// Fetch with rate limiting
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch(`https://api.github.com/users/${encodeURIComponent(username)}`, {
signal: controller.signal,
headers: {
'Accept': 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28'
}
});
if (!response.ok) {
if (response.status === 403) {
const resetTime = response.headers.get('X-RateLimit-Reset');
throw new Error(`Rate limited. Reset at ${new Date(parseInt(resetTime) * 1000).toISOString()}`);
}
throw new Error(`GitHub API error: ${response.status} ${response.statusText}`);
}
const data = await response.json();
localStorage.setItem(cacheKey, JSON.stringify({ data, timestamp: Date.now() }));
return data;
} catch (error) {
if (error.name === 'AbortError') {
throw new Error('Request timed out after 5 seconds');
}
throw error;
} finally {
clearTimeout(timeoutId);
}
}
// Unit test stubs (Jest)
/**
* @jest-environment jsdom
*/
describe('fetchGitHubUser', () => {
beforeEach(() => {
localStorage.clear();
global.fetch = jest.fn();
});
it('should return user data for valid username', async () => {
const mockData = {
login: 'octocat',
name: 'The Octocat',
avatar_url: 'https://avatars.githubusercontent.com/u/583231?v=4',
public_repos: 8
};
global.fetch.mockResolvedValueOnce({
ok: true,
json: () => Promise.resolve(mockData)
});
const result = await fetchGitHubUser('octocat');
expect(result).toEqual(mockData);
expect(localStorage.getItem('github_user_octocat')).toBeTruthy();
});
it('should throw for invalid username', async () => {
await expect(fetchGitHubUser('')).rejects.toThrow('Username must be a non-empty string');
});
});
```skills-collection
Take a free 3-minute scan and get personalized AI skill recommendations.
Take free scan