javascript-pro

Write modern JavaScript with ES6+ features, async patterns, and Node.js APIs. Use when writing JavaScript code, debugging async issues, handling promises, optimizing JS performance, or working with the event loop.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "javascript-pro" with this command: npx skills add arosenkranz/claude-code-config/arosenkranz-claude-code-config-javascript-pro

JavaScript Pro

Guidelines for modern JavaScript and async programming patterns.

Core Principles

  1. Async/await over promise chains - Cleaner, more readable code
  2. Functional patterns - Map, filter, reduce over imperative loops
  3. Error boundaries - Handle errors at appropriate levels
  4. Module-first - ES modules with clean exports
  5. Defensive coding - Nullish coalescing and optional chaining

Modern Syntax (ES2020+)

Nullish Coalescing and Optional Chaining

// Nullish coalescing (??) - only null/undefined
const port = config.port ?? 3000;

// Optional chaining (?.)
const city = user?.address?.city;
const result = obj.method?.();

// Combined pattern
const name = data?.user?.name ?? 'Anonymous';

Destructuring and Spread

// Nested destructuring with defaults
const { user: { name = 'Guest', role = 'viewer' } = {} } = response;

// Rest in destructuring
const { id, ...rest } = obj;

// Spread for immutable updates
const updated = { ...original, status: 'active' };
const combined = [...arr1, ...arr2];

Modern Array Methods

// Array.at() for negative indexing
const last = arr.at(-1);

// Object.fromEntries() for object creation
const obj = Object.fromEntries([['a', 1], ['b', 2]]);

// Array.prototype.flatMap()
const words = sentences.flatMap(s => s.split(' '));

// Object.hasOwn() (safer than hasOwnProperty)
if (Object.hasOwn(obj, 'key')) { }

Async Patterns

Promise Combinators

// Promise.all - fail fast, all must succeed
const [users, posts] = await Promise.all([
  fetchUsers(),
  fetchPosts()
]);

// Promise.allSettled - get all results regardless of failures
const results = await Promise.allSettled([
  riskyOperation1(),
  riskyOperation2()
]);
const successes = results.filter(r => r.status === 'fulfilled');

// Promise.race - first to complete wins
const result = await Promise.race([
  fetchData(),
  timeout(5000)
]);

// Promise.any - first success wins (ignores rejections)
const fastest = await Promise.any([
  fetchFromCDN1(),
  fetchFromCDN2()
]);

Async Error Handling

// Wrapper for clean try/catch
async function safeAsync(promise) {
  try {
    const data = await promise;
    return [data, null];
  } catch (error) {
    return [null, error];
  }
}

// Usage
const [user, error] = await safeAsync(fetchUser(id));
if (error) {
  console.error('Failed to fetch user:', error.message);
  return;
}

Async Iteration

// for-await-of for async iterables
async function* paginate(url) {
  let nextUrl = url;
  while (nextUrl) {
    const response = await fetch(nextUrl);
    const data = await response.json();
    yield data.items;
    nextUrl = data.nextPage;
  }
}

for await (const page of paginate('/api/items')) {
  processItems(page);
}

Controlled Concurrency

async function processWithLimit(items, fn, limit = 5) {
  const results = [];
  const executing = new Set();

  for (const item of items) {
    const promise = fn(item).then(result => {
      executing.delete(promise);
      return result;
    });
    executing.add(promise);
    results.push(promise);

    if (executing.size >= limit) {
      await Promise.race(executing);
    }
  }

  return Promise.all(results);
}

Module Patterns

Clean Exports

// Named exports for utilities
export function formatDate(date) { }
export function parseDate(str) { }

// Default export for main class/function
export default class ApiClient { }

// Re-exports for barrel files
export { formatDate, parseDate } from './dates.js';
export { default as ApiClient } from './client.js';

Dynamic Imports

// Code splitting with dynamic imports
const module = await import('./heavy-module.js');

// Conditional loading
if (featureEnabled) {
  const { Feature } = await import('./feature.js');
  new Feature().init();
}

Node.js Patterns

File System (fs/promises)

import { readFile, writeFile, mkdir } from 'fs/promises';
import { existsSync } from 'fs';

async function ensureDir(path) {
  if (!existsSync(path)) {
    await mkdir(path, { recursive: true });
  }
}

const content = await readFile('config.json', 'utf-8');
const config = JSON.parse(content);

Streams

import { createReadStream, createWriteStream } from 'fs';
import { pipeline } from 'stream/promises';
import { createGzip } from 'zlib';

await pipeline(
  createReadStream('input.txt'),
  createGzip(),
  createWriteStream('output.txt.gz')
);

Testing Patterns

import { describe, it, expect, vi } from 'vitest';

describe('UserService', () => {
  it('fetches user by id', async () => {
    const mockFetch = vi.fn().mockResolvedValue({
      json: () => Promise.resolve({ id: 1, name: 'Test' })
    });

    const user = await fetchUser(1, { fetch: mockFetch });

    expect(user.name).toBe('Test');
    expect(mockFetch).toHaveBeenCalledWith('/api/users/1');
  });
});

Performance Tips

  • Use Map/Set for frequent lookups (O(1) vs O(n))
  • Avoid creating functions in loops
  • Use requestAnimationFrame for DOM updates
  • Debounce/throttle event handlers
  • Prefer for...of over forEach for break/continue support

Common Anti-Patterns

  • Using == instead of ===
  • Not handling promise rejections
  • Modifying objects during iteration
  • Using var instead of const/let
  • Callback hell instead of async/await
  • Not using optional chaining for nested access

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

session-log

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

homelab-helper

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

instinct-export

No summary provided by upstream source.

Repository SourceNeeds Review