All skills
jeffallan avatar

/javascript-pro

@efebc44
by jeffallanjeffallan/claude-skills12k stars
1,124

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.

Use this Skill: https://skilld.dev/gh/jeffallan/claude-skills/javascript-pro

This session only. Nothing lands on disk.

referencesmodern-syntax.md

≈1.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Modern JavaScript Syntax (ES2023+)

Optional Chaining and Nullish Coalescing

// Optional chaining - safe property access
const userName = user?.profile?.name;
const firstItem = items?.[0];
const result = api?.fetchData?.();

// Nullish coalescing - default only for null/undefined
const port = config.port ?? 3000;
const name = user.name ?? 'Anonymous';

// Combining both patterns
const displayName = user?.profile?.name ?? user?.email ?? 'Guest';

// Optional chaining with delete
delete user?.temporaryData?.cache;

Private Class Fields

class BankAccount {
  // Private fields
  #balance = 0;
  #accountNumber;

  // Private method
  #validateAmount(amount) {
    if (amount <= 0) throw new Error('Invalid amount');
  }

  constructor(accountNumber, initialBalance = 0) {
    this.#accountNumber = accountNumber;
    this.#balance = initialBalance;
  }

  deposit(amount) {
    this.#validateAmount(amount);
    this.#balance += amount;
    return this.#balance;
  }

  getBalance() {
    return this.#balance;
  }
}

// Static private fields
class Config {
  static #apiKey = process.env.API_KEY;

  static getApiKey() {
    return this.#apiKey;
  }
}

Top-Level Await

// No need for async IIFE wrapper
const data = await fetch('/api/config').then(r => r.json());
const db = await connectDatabase(data.dbUrl);

// Dynamic imports with await
const module = await import(`./modules/${moduleName}.js`);

// Error handling at top level
try {
  const config = await loadConfig();
  startServer(config);
} catch (error) {
  console.error('Failed to start:', error);
  process.exit(1);
}

Array Methods (Modern)

// at() - negative indexing
const last = items.at(-1);
const secondLast = items.at(-2);

// findLast() and findLastIndex()
const lastEven = numbers.findLast(n => n % 2 === 0);
const lastIndex = numbers.findLastIndex(n => n > 10);

// toSorted(), toReversed(), toSpliced() - non-mutating
const sorted = items.toSorted((a, b) => a - b);
const reversed = items.toReversed();
const spliced = items.toSpliced(1, 2, 'new');

// with() - replace at index
const updated = items.with(2, 'newValue');

// flatMap() for transform and flatten
const nestedResults = users.flatMap(user => user.posts);

Object and String Enhancements

// Object.groupBy() - group array elements
const groupedByAge = Object.groupBy(users, user => user.age);
const groupedByStatus = Object.groupBy(orders, o => o.status);

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

// String.prototype.at()
const firstChar = str.at(0);
const lastChar = str.at(-1);

// replaceAll()
const cleaned = text.replaceAll('old', 'new');
const sanitized = input.replaceAll(/[<>]/g, '');

WeakRef and FinalizationRegistry

// WeakRef - hold weak references to objects
class Cache {
  #cache = new Map();

  set(key, value) {
    this.#cache.set(key, new WeakRef(value));
  }

  get(key) {
    const ref = this.#cache.get(key);
    return ref?.deref(); // undefined if GC'd
  }
}

// FinalizationRegistry - cleanup callbacks
const registry = new FinalizationRegistry((heldValue) => {
  console.log(`Cleanup: ${heldValue}`);
  // Release resources
});

class Resource {
  constructor(id) {
    this.id = id;
    registry.register(this, id, this);
  }

  dispose() {
    registry.unregister(this);
  }
}

Logical Assignment Operators

// ||= - assign if falsy
config.timeout ||= 5000;
user.name ||= 'Anonymous';

// &&= - assign if truthy
user.profile &&= sanitize(user.profile);

// ??= - assign if nullish
options.port ??= 3000;
settings.theme ??= 'dark';

Numeric Separators and BigInt

// Numeric separators for readability
const billion = 1_000_000_000;
const bytes = 0xFF_EC_DE_5E;
const trillion = 1_000_000_000_000n;

// BigInt for large integers
const hugeNumber = 9007199254740991n;
const result = hugeNumber + 1n;
const mixed = BigInt(123) + 456n;

// BigInt operations
const divided = 10n / 3n; // 3n (truncates)
const power = 2n ** 64n;

Pattern Matching (Stage 3 Proposal)

// Using switch with enhanced patterns (when available)
function processValue(value) {
  switch (true) {
    case typeof value === 'string':
      return value.toUpperCase();
    case typeof value === 'number':
      return value * 2;
    case Array.isArray(value):
      return value.length;
    default:
      return null;
  }
}

// Object destructuring patterns
function handleResponse({ status, data, error }) {
  if (error) throw error;
  if (status === 200) return data;
  return null;
}

Iterator Helpers (Stage 3)

// When available - chaining iterator operations
const result = [1, 2, 3, 4, 5]
  .values()
  .map(x => x * 2)
  .filter(x => x > 5)
  .toArray();

// Custom iterators
const range = {
  *[Symbol.iterator]() {
    for (let i = 0; i < 10; i++) {
      yield i;
    }
  }
};

for (const num of range) {
  console.log(num);
}

Temporal API (Stage 3)

// Modern date/time handling (when available)
import { Temporal } from '@js-temporal/polyfill';

const now = Temporal.Now.instant();
const date = Temporal.PlainDate.from('2024-01-15');
const time = Temporal.PlainTime.from('14:30:00');

// Duration calculations
const duration = Temporal.Duration.from({ hours: 2, minutes: 30 });
const later = now.add(duration);

// Timezone handling
const zonedTime = now.toZonedDateTimeISO('America/New_York');

Quick Reference

Feature ES Version Syntax
Optional chaining ES2020 obj?.prop
Nullish coalescing ES2020 value ?? default
Private fields ES2022 #fieldName
Top-level await ES2022 await import()
Logical assignment ES2021 x ??= y
Array.at() ES2022 arr.at(-1)
Object.hasOwn() ES2022 Object.hasOwn(obj, 'key')
Array.findLast() ES2023 arr.findLast(fn)
toSorted() ES2023 arr.toSorted()

Source: SKILL.md on GitHub

1 alert17d5 checks · Risk CRITICAL
  • Gen Agent Trust Hub17d

    The skill has been flagged by multiple automated security scanners for containing malicious content. Specifically, the documentation URL is blacklisted by reputation services, and the main skill file (SKILL.md) has been identified as having a malicious reputation (FileRepMalware). Additionally, the skill's capability to process external code files combined with its access to sensitive system APIs (network, file system, subprocess) creates a significant attack surface for indirect prompt injection.

  • Socket17d

    1 alert: gptAnomaly

  • Snyk17d

    Risk: LOW · No issues

  • Runlayer6mo

    6 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at efebc44. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 5 months ago
Other metadata
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"
}

README badge

README badge for jeffallan/claude-skills/javascript-pro