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.

referencesbrowser-apis.md

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

Browser APIs

Fetch API

// Basic GET request
const response = await fetch('/api/users');
const data = await response.json();

// POST with JSON
const response = await fetch('/api/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ name: 'John', email: 'john@example.com' })
});

// Error handling
const fetchWithErrorHandling = async (url) => {
  try {
    const response = await fetch(url);

    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }

    return await response.json();
  } catch (error) {
    if (error.name === 'TypeError') {
      console.error('Network error or CORS issue');
    }
    throw error;
  }
};

// Abort requests
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);

const response = await fetch('/api/data', {
  signal: controller.signal
});

// File upload with progress
const uploadFile = async (file) => {
  const formData = new FormData();
  formData.append('file', file);

  return fetch('/api/upload', {
    method: 'POST',
    body: formData,
  });
};

Web Workers

// main.js - Create and communicate with worker
const worker = new Worker('/worker.js');

worker.postMessage({ command: 'process', data: largeArray });

worker.onmessage = (event) => {
  console.log('Result from worker:', event.data);
};

worker.onerror = (error) => {
  console.error('Worker error:', error.message);
};

// Terminate when done
worker.terminate();

// worker.js - Worker code
self.onmessage = (event) => {
  const { command, data } = event.data;

  if (command === 'process') {
    const result = processLargeData(data);
    self.postMessage(result);
  }
};

function processLargeData(data) {
  // CPU-intensive work
  return data.map(x => x * 2).reduce((a, b) => a + b, 0);
}

// Shared Worker (shared between tabs)
const sharedWorker = new SharedWorker('/shared-worker.js');

sharedWorker.port.onmessage = (event) => {
  console.log('Shared worker message:', event.data);
};

sharedWorker.port.postMessage({ type: 'init' });

Service Workers & PWA

// Register Service Worker
if ('serviceWorker' in navigator) {
  const registration = await navigator.serviceWorker.register('/sw.js');
  console.log('SW registered:', registration);

  // Update service worker
  registration.addEventListener('updatefound', () => {
    const newWorker = registration.installing;
    newWorker.addEventListener('statechange', () => {
      if (newWorker.state === 'activated') {
        window.location.reload();
      }
    });
  });
}

// sw.js - Service Worker
const CACHE_NAME = 'v1';
const urlsToCache = ['/index.html', '/styles.css', '/app.js'];

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches.open(CACHE_NAME).then((cache) => {
      return cache.addAll(urlsToCache);
    })
  );
});

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then((response) => {
      // Cache hit - return response
      if (response) {
        return response;
      }

      // Clone request
      const fetchRequest = event.request.clone();

      return fetch(fetchRequest).then((response) => {
        if (!response || response.status !== 200 || response.type !== 'basic') {
          return response;
        }

        const responseToCache = response.clone();

        caches.open(CACHE_NAME).then((cache) => {
          cache.put(event.request, responseToCache);
        });

        return response;
      });
    })
  );
});

// Background sync
self.addEventListener('sync', (event) => {
  if (event.tag === 'sync-messages') {
    event.waitUntil(syncMessages());
  }
});

Local Storage & IndexedDB

// LocalStorage (synchronous, max 5-10MB)
localStorage.setItem('theme', 'dark');
const theme = localStorage.getItem('theme');
localStorage.removeItem('theme');
localStorage.clear();

// SessionStorage (per-tab)
sessionStorage.setItem('token', 'abc123');

// IndexedDB (asynchronous, larger storage)
const openDB = () => {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open('myDatabase', 1);

    request.onerror = () => reject(request.error);
    request.onsuccess = () => resolve(request.result);

    request.onupgradeneeded = (event) => {
      const db = event.target.result;
      const objectStore = db.createObjectStore('users', { keyPath: 'id' });
      objectStore.createIndex('email', 'email', { unique: true });
    };
  });
};

const addUser = async (user) => {
  const db = await openDB();
  return new Promise((resolve, reject) => {
    const transaction = db.transaction(['users'], 'readwrite');
    const objectStore = transaction.objectStore('users');
    const request = objectStore.add(user);

    request.onsuccess = () => resolve(request.result);
    request.onerror = () => reject(request.error);
  });
};

const getUser = async (id) => {
  const db = await openDB();
  return new Promise((resolve, reject) => {
    const transaction = db.transaction(['users']);
    const objectStore = transaction.objectStore('users');
    const request = objectStore.get(id);

    request.onsuccess = () => resolve(request.result);
    request.onerror = () => reject(request.error);
  });
};

Intersection Observer

// Lazy loading images
const imageObserver = new IntersectionObserver(
  (entries, observer) => {
    entries.forEach((entry) => {
      if (entry.isIntersecting) {
        const img = entry.target;
        img.src = img.dataset.src;
        img.classList.add('loaded');
        observer.unobserve(img);
      }
    });
  },
  {
    root: null, // viewport
    rootMargin: '50px',
    threshold: 0.1
  }
);

document.querySelectorAll('img[data-src]').forEach((img) => {
  imageObserver.observe(img);
});

// Infinite scroll
const loadMoreObserver = new IntersectionObserver(
  (entries) => {
    const lastEntry = entries[0];
    if (lastEntry.isIntersecting) {
      loadMoreItems();
    }
  },
  { threshold: 1.0 }
);

const sentinel = document.querySelector('#load-more-sentinel');
loadMoreObserver.observe(sentinel);

Mutation Observer

// Watch DOM changes
const observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    if (mutation.type === 'childList') {
      console.log('Nodes added/removed:', mutation.addedNodes, mutation.removedNodes);
    } else if (mutation.type === 'attributes') {
      console.log('Attribute changed:', mutation.attributeName);
    }
  });
});

observer.observe(document.body, {
  childList: true,
  attributes: true,
  subtree: true,
  attributeOldValue: true
});

// Disconnect when done
observer.disconnect();

Web Notifications

// Request permission
const permission = await Notification.requestPermission();

if (permission === 'granted') {
  new Notification('Hello!', {
    body: 'This is a notification',
    icon: '/icon.png',
    tag: 'unique-tag',
    requireInteraction: false
  });
}

// Service Worker notifications
// sw.js
self.addEventListener('push', (event) => {
  const data = event.data.json();

  event.waitUntil(
    self.registration.showNotification(data.title, {
      body: data.body,
      icon: data.icon,
      badge: '/badge.png',
      data: data.url
    })
  );
});

self.addEventListener('notificationclick', (event) => {
  event.notification.close();
  event.waitUntil(
    clients.openWindow(event.notification.data)
  );
});

Canvas & WebGL

// Canvas 2D
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');

// Draw rectangle
ctx.fillStyle = '#FF0000';
ctx.fillRect(10, 10, 100, 100);

// Draw text
ctx.font = '30px Arial';
ctx.fillText('Hello Canvas', 10, 50);

// Draw image
const img = new Image();
img.onload = () => {
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
img.src = '/image.png';

// WebGL basic setup
const gl = canvas.getContext('webgl2');

if (!gl) {
  console.error('WebGL2 not supported');
}

// Clear canvas
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

Performance APIs

// Performance timing
const timing = performance.timing;
const loadTime = timing.loadEventEnd - timing.navigationStart;
console.log('Page load time:', loadTime);

// Performance Observer
const observer = new PerformanceObserver((list) => {
  for (const entry of list.getEntries()) {
    console.log(`${entry.name}: ${entry.duration}ms`);
  }
});

observer.observe({ entryTypes: ['measure', 'navigation', 'resource'] });

// Custom marks and measures
performance.mark('start-fetch');
await fetch('/api/data');
performance.mark('end-fetch');
performance.measure('fetch-duration', 'start-fetch', 'end-fetch');

const measures = performance.getEntriesByType('measure');
console.log(measures);

Quick Reference

API Use Case Browser Support
Fetch HTTP requests Modern browsers
Web Workers CPU-intensive tasks Modern browsers
Service Workers Offline, caching Modern browsers
IndexedDB Large client storage Modern browsers
IntersectionObserver Lazy loading, infinite scroll Modern browsers
MutationObserver DOM change detection Modern browsers
Notifications User alerts Modern browsers (permission)
Canvas 2D graphics All browsers
WebGL 3D graphics Modern browsers

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