Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    Microck

    modern-javascript-patterns

    Microck/modern-javascript-patterns
    Productivity
    116
    1 installs

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Master ES6+ features including async/await, destructuring, spread operators, arrow functions, promises, modules, iterators, generators, and functional programming patterns for writing clean,...

    SKILL.md

    Modern JavaScript Patterns

    Comprehensive guide for mastering modern JavaScript (ES6+) features, functional programming patterns, and best practices for writing clean, maintainable, and performant code.

    When to Use This Skill

    • Refactoring legacy JavaScript to modern syntax
    • Implementing functional programming patterns
    • Optimizing JavaScript performance
    • Writing maintainable and readable code
    • Working with asynchronous operations
    • Building modern web applications
    • Migrating from callbacks to Promises/async-await
    • Implementing data transformation pipelines

    ES6+ Core Features

    1. Arrow Functions

    Syntax and Use Cases:

    // Traditional function
    function add(a, b) {
      return a + b;
    }
    
    // Arrow function
    const add = (a, b) => a + b;
    
    // Single parameter (parentheses optional)
    const double = x => x * 2;
    
    // No parameters
    const getRandom = () => Math.random();
    
    // Multiple statements (need curly braces)
    const processUser = user => {
      const normalized = user.name.toLowerCase();
      return { ...user, name: normalized };
    };
    
    // Returning objects (wrap in parentheses)
    const createUser = (name, age) => ({ name, age });
    

    Lexical 'this' Binding:

    class Counter {
      constructor() {
        this.count = 0;
      }
    
      // Arrow function preserves 'this' context
      increment = () => {
        this.count++;
      };
    
      // Traditional function loses 'this' in callbacks
      incrementTraditional() {
        setTimeout(function() {
          this.count++;  // 'this' is undefined
        }, 1000);
      }
    
      // Arrow function maintains 'this'
      incrementArrow() {
        setTimeout(() => {
          this.count++;  // 'this' refers to Counter instance
        }, 1000);
      }
    }
    

    2. Destructuring

    Object Destructuring:

    const user = {
      id: 1,
      name: 'John Doe',
      email: 'john@example.com',
      address: {
        city: 'New York',
        country: 'USA'
      }
    };
    
    // Basic destructuring
    const { name, email } = user;
    
    // Rename variables
    const { name: userName, email: userEmail } = user;
    
    // Default values
    const { age = 25 } = user;
    
    // Nested destructuring
    const { address: { city, country } } = user;
    
    // Rest operator
    const { id, ...userWithoutId } = user;
    
    // Function parameters
    function greet({ name, age = 18 }) {
      console.log(`Hello ${name}, you are ${age}`);
    }
    greet(user);
    

    Array Destructuring:

    const numbers = [1, 2, 3, 4, 5];
    
    // Basic destructuring
    const [first, second] = numbers;
    
    // Skip elements
    const [, , third] = numbers;
    
    // Rest operator
    const [head, ...tail] = numbers;
    
    // Swapping variables
    let a = 1, b = 2;
    [a, b] = [b, a];
    
    // Function return values
    function getCoordinates() {
      return [10, 20];
    }
    const [x, y] = getCoordinates();
    
    // Default values
    const [one, two, three = 0] = [1, 2];
    

    3. Spread and Rest Operators

    Spread Operator:

    // Array spreading
    const arr1 = [1, 2, 3];
    const arr2 = [4, 5, 6];
    const combined = [...arr1, ...arr2];
    
    // Object spreading
    const defaults = { theme: 'dark', lang: 'en' };
    const userPrefs = { theme: 'light' };
    const settings = { ...defaults, ...userPrefs };
    
    // Function arguments
    const numbers = [1, 2, 3];
    Math.max(...numbers);
    
    // Copying arrays/objects (shallow copy)
    const copy = [...arr1];
    const objCopy = { ...user };
    
    // Adding items immutably
    const newArr = [...arr1, 4, 5];
    const newObj = { ...user, age: 30 };
    

    Rest Parameters:

    // Collect function arguments
    function sum(...numbers) {
      return numbers.reduce((total, num) => total + num, 0);
    }
    sum(1, 2, 3, 4, 5);
    
    // With regular parameters
    function greet(greeting, ...names) {
      return `${greeting} ${names.join(', ')}`;
    }
    greet('Hello', 'John', 'Jane', 'Bob');
    
    // Object rest
    const { id, ...userData } = user;
    
    // Array rest
    const [first, ...rest] = [1, 2, 3, 4, 5];
    

    4. Template Literals

    // Basic usage
    const name = 'John';
    const greeting = `Hello, ${name}!`;
    
    // Multi-line strings
    const html = `
      <div>
        <h1>${title}</h1>
        <p>${content}</p>
      </div>
    `;
    
    // Expression evaluation
    const price = 19.99;
    const total = `Total: $${(price * 1.2).toFixed(2)}`;
    
    // Tagged template literals
    function highlight(strings, ...values) {
      return strings.reduce((result, str, i) => {
        const value = values[i] || '';
        return result + str + `<mark>${value}</mark>`;
      }, '');
    }
    
    const name = 'John';
    const age = 30;
    const html = highlight`Name: ${name}, Age: ${age}`;
    // Output: "Name: <mark>John</mark>, Age: <mark>30</mark>"
    

    5. Enhanced Object Literals

    const name = 'John';
    const age = 30;
    
    // Shorthand property names
    const user = { name, age };
    
    // Shorthand method names
    const calculator = {
      add(a, b) {
        return a + b;
      },
      subtract(a, b) {
        return a - b;
      }
    };
    
    // Computed property names
    const field = 'email';
    const user = {
      name: 'John',
      [field]: 'john@example.com',
      [`get${field.charAt(0).toUpperCase()}${field.slice(1)}`]() {
        return this[field];
      }
    };
    
    // Dynamic property creation
    const createUser = (name, ...props) => {
      return props.reduce((user, [key, value]) => ({
        ...user,
        [key]: value
      }), { name });
    };
    
    const user = createUser('John', ['age', 30], ['email', 'john@example.com']);
    

    Asynchronous Patterns

    1. Promises

    Creating and Using Promises:

    // Creating a promise
    const fetchUser = (id) => {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          if (id > 0) {
            resolve({ id, name: 'John' });
          } else {
            reject(new Error('Invalid ID'));
          }
        }, 1000);
      });
    };
    
    // Using promises
    fetchUser(1)
      .then(user => console.log(user))
      .catch(error => console.error(error))
      .finally(() => console.log('Done'));
    
    // Chaining promises
    fetchUser(1)
      .then(user => fetchUserPosts(user.id))
      .then(posts => processPosts(posts))
      .then(result => console.log(result))
      .catch(error => console.error(error));
    

    Promise Combinators:

    // Promise.all - Wait for all promises
    const promises = [
      fetchUser(1),
      fetchUser(2),
      fetchUser(3)
    ];
    
    Promise.all(promises)
      .then(users => console.log(users))
      .catch(error => console.error('At least one failed:', error));
    
    // Promise.allSettled - Wait for all, regardless of outcome
    Promise.allSettled(promises)
      .then(results => {
        results.forEach(result => {
          if (result.status === 'fulfilled') {
            console.log('Success:', result.value);
          } else {
            console.log('Error:', result.reason);
          }
        });
      });
    
    // Promise.race - First to complete
    Promise.race(promises)
      .then(winner => console.log('First:', winner))
      .catch(error => console.error(error));
    
    // Promise.any - First to succeed
    Promise.any(promises)
      .then(first => console.log('First success:', first))
      .catch(error => console.error('All failed:', error));
    

    2. Async/Await

    Basic Usage:

    // Async function always returns a Promise
    async function fetchUser(id) {
      const response = await fetch(`/api/users/${id}`);
      const user = await response.json();
      return user;
    }
    
    // Error handling with try/catch
    async function getUserData(id) {
      try {
        const user = await fetchUser(id);
        const posts = await fetchUserPosts(user.id);
        return { user, posts };
      } catch (error) {
        console.error('Error fetching data:', error);
        throw error;
      }
    }
    
    // Sequential vs Parallel execution
    async function sequential() {
      const user1 = await fetchUser(1);  // Wait
      const user2 = await fetchUser(2);  // Then wait
      return [user1, user2];
    }
    
    async function parallel() {
      const [user1, user2] = await Promise.all([
        fetchUser(1),
        fetchUser(2)
      ]);
      return [user1, user2];
    }
    

    Advanced Patterns:

    // Async IIFE
    (async () => {
      const result = await someAsyncOperation();
      console.log(result);
    })();
    
    // Async iteration
    async function processUsers(userIds) {
      for (const id of userIds) {
        const user = await fetchUser(id);
        await processUser(user);
      }
    }
    
    // Top-level await (ES2022)
    const config = await fetch('/config.json').then(r => r.json());
    
    // Retry logic
    async function fetchWithRetry(url, retries = 3) {
      for (let i = 0; i < retries; i++) {
        try {
          return await fetch(url);
        } catch (error) {
          if (i === retries - 1) throw error;
          await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
        }
      }
    }
    
    // Timeout wrapper
    async function withTimeout(promise, ms) {
      const timeout = new Promise((_, reject) =>
        setTimeout(() => reject(new Error('Timeout')), ms)
      );
      return Promise.race([promise, timeout]);
    }
    

    Functional Programming Patterns

    1. Array Methods

    Map, Filter, Reduce:

    const users = [
      { id: 1, name: 'John', age: 30, active: true },
      { id: 2, name: 'Jane', age: 25, active: false },
      { id: 3, name: 'Bob', age: 35, active: true }
    ];
    
    // Map - Transform array
    const names = users.map(user => user.name);
    const upperNames = users.map(user => user.name.toUpperCase());
    
    // Filter - Select elements
    const activeUsers = users.filter(user => user.active);
    const adults = users.filter(user => user.age >= 18);
    
    // Reduce - Aggregate data
    const totalAge = users.reduce((sum, user) => sum + user.age, 0);
    const avgAge = totalAge / users.length;
    
    // Group by property
    const byActive = users.reduce((groups, user) => {
      const key = user.active ? 'active' : 'inactive';
      return {
        ...groups,
        [key]: [...(groups[key] || []), user]
      };
    }, {});
    
    // Chaining methods
    const result = users
      .filter(user => user.active)
      .map(user => user.name)
      .sort()
      .join(', ');
    

    Advanced Array Methods:

    // Find - First matching element
    const user = users.find(u => u.id === 2);
    
    // FindIndex - Index of first match
    const index = users.findIndex(u => u.name === 'Jane');
    
    // Some - At least one matches
    const hasActive = users.some(u => u.active);
    
    // Every - All match
    const allAdults = users.every(u => u.age >= 18);
    
    // FlatMap - Map and flatten
    const userTags = [
      { name: 'John', tags: ['admin', 'user'] },
      { name: 'Jane', tags: ['user'] }
    ];
    const allTags = userTags.flatMap(u => u.tags);
    
    // From - Create array from iterable
    const str = 'hello';
    const chars = Array.from(str);
    const numbers = Array.from({ length: 5 }, (_, i) => i + 1);
    
    // Of - Create array from arguments
    const arr = Array.of(1, 2, 3);
    

    2. Higher-Order Functions

    Functions as Arguments:

    // Custom forEach
    function forEach(array, callback) {
      for (let i = 0; i < array.length; i++) {
        callback(array[i], i, array);
      }
    }
    
    // Custom map
    function map(array, transform) {
      const result = [];
      for (const item of array) {
        result.push(transform(item));
      }
      return result;
    }
    
    // Custom filter
    function filter(array, predicate) {
      const result = [];
      for (const item of array) {
        if (predicate(item)) {
          result.push(item);
        }
      }
      return result;
    }
    

    Functions Returning Functions:

    // Currying
    const multiply = a => b => a * b;
    const double = multiply(2);
    const triple = multiply(3);
    
    console.log(double(5));  // 10
    console.log(triple(5));  // 15
    
    // Partial application
    function partial(fn, ...args) {
      return (...moreArgs) => fn(...args, ...moreArgs);
    }
    
    const add = (a, b, c) => a + b + c;
    const add5 = partial(add, 5);
    console.log(add5(3, 2));  // 10
    
    // Memoization
    function memoize(fn) {
      const cache = new Map();
      return (...args) => {
        const key = JSON.stringify(args);
        if (cache.has(key)) {
          return cache.get(key);
        }
        const result = fn(...args);
        cache.set(key, result);
        return result;
      };
    }
    
    const fibonacci = memoize((n) => {
      if (n <= 1) return n;
      return fibonacci(n - 1) + fibonacci(n - 2);
    });
    

    3. Composition and Piping

    // Function composition
    const compose = (...fns) => x =>
      fns.reduceRight((acc, fn) => fn(acc), x);
    
    const pipe = (...fns) => x =>
      fns.reduce((acc, fn) => fn(acc), x);
    
    // Example usage
    const addOne = x => x + 1;
    const double = x => x * 2;
    const square = x => x * x;
    
    const composed = compose(square, double, addOne);
    console.log(composed(3));  // ((3 + 1) * 2)^2 = 64
    
    const piped = pipe(addOne, double, square);
    console.log(piped(3));  // ((3 + 1) * 2)^2 = 64
    
    // Practical example
    const processUser = pipe(
      user => ({ ...user, name: user.name.trim() }),
      user => ({ ...user, email: user.email.toLowerCase() }),
      user => ({ ...user, age: parseInt(user.age) })
    );
    
    const user = processUser({
      name: '  John  ',
      email: 'JOHN@EXAMPLE.COM',
      age: '30'
    });
    

    4. Pure Functions and Immutability

    // Impure function (modifies input)
    function addItemImpure(cart, item) {
      cart.items.push(item);
      cart.total += item.price;
      return cart;
    }
    
    // Pure function (no side effects)
    function addItemPure(cart, item) {
      return {
        ...cart,
        items: [...cart.items, item],
        total: cart.total + item.price
      };
    }
    
    // Immutable array operations
    const numbers = [1, 2, 3, 4, 5];
    
    // Add to array
    const withSix = [...numbers, 6];
    
    // Remove from array
    const withoutThree = numbers.filter(n => n !== 3);
    
    // Update array element
    const doubled = numbers.map(n => n === 3 ? n * 2 : n);
    
    // Immutable object operations
    const user = { name: 'John', age: 30 };
    
    // Update property
    const olderUser = { ...user, age: 31 };
    
    // Add property
    const withEmail = { ...user, email: 'john@example.com' };
    
    // Remove property
    const { age, ...withoutAge } = user;
    
    // Deep cloning (simple approach)
    const deepClone = obj => JSON.parse(JSON.stringify(obj));
    
    // Better deep cloning
    const structuredClone = obj => globalThis.structuredClone(obj);
    

    Modern Class Features

    // Class syntax
    class User {
      // Private fields
      #password;
    
      // Public fields
      id;
      name;
    
      // Static field
      static count = 0;
    
      constructor(id, name, password) {
        this.id = id;
        this.name = name;
        this.#password = password;
        User.count++;
      }
    
      // Public method
      greet() {
        return `Hello, ${this.name}`;
      }
    
      // Private method
      #hashPassword(password) {
        return `hashed_${password}`;
      }
    
      // Getter
      get displayName() {
        return this.name.toUpperCase();
      }
    
      // Setter
      set password(newPassword) {
        this.#password = this.#hashPassword(newPassword);
      }
    
      // Static method
      static create(id, name, password) {
        return new User(id, name, password);
      }
    }
    
    // Inheritance
    class Admin extends User {
      constructor(id, name, password, role) {
        super(id, name, password);
        this.role = role;
      }
    
      greet() {
        return `${super.greet()}, I'm an admin`;
      }
    }
    

    Modules (ES6)

    // Exporting
    // math.js
    export const PI = 3.14159;
    export function add(a, b) {
      return a + b;
    }
    export class Calculator {
      // ...
    }
    
    // Default export
    export default function multiply(a, b) {
      return a * b;
    }
    
    // Importing
    // app.js
    import multiply, { PI, add, Calculator } from './math.js';
    
    // Rename imports
    import { add as sum } from './math.js';
    
    // Import all
    import * as Math from './math.js';
    
    // Dynamic imports
    const module = await import('./math.js');
    const { add } = await import('./math.js');
    
    // Conditional loading
    if (condition) {
      const module = await import('./feature.js');
      module.init();
    }
    

    Iterators and Generators

    // Custom iterator
    const range = {
      from: 1,
      to: 5,
    
      [Symbol.iterator]() {
        return {
          current: this.from,
          last: this.to,
    
          next() {
            if (this.current <= this.last) {
              return { done: false, value: this.current++ };
            } else {
              return { done: true };
            }
          }
        };
      }
    };
    
    for (const num of range) {
      console.log(num);  // 1, 2, 3, 4, 5
    }
    
    // Generator function
    function* rangeGenerator(from, to) {
      for (let i = from; i <= to; i++) {
        yield i;
      }
    }
    
    for (const num of rangeGenerator(1, 5)) {
      console.log(num);
    }
    
    // Infinite generator
    function* fibonacci() {
      let [prev, curr] = [0, 1];
      while (true) {
        yield curr;
        [prev, curr] = [curr, prev + curr];
      }
    }
    
    // Async generator
    async function* fetchPages(url) {
      let page = 1;
      while (true) {
        const response = await fetch(`${url}?page=${page}`);
        const data = await response.json();
        if (data.length === 0) break;
        yield data;
        page++;
      }
    }
    
    for await (const page of fetchPages('/api/users')) {
      console.log(page);
    }
    

    Modern Operators

    // Optional chaining
    const user = { name: 'John', address: { city: 'NYC' } };
    const city = user?.address?.city;
    const zipCode = user?.address?.zipCode;  // undefined
    
    // Function call
    const result = obj.method?.();
    
    // Array access
    const first = arr?.[0];
    
    // Nullish coalescing
    const value = null ?? 'default';      // 'default'
    const value = undefined ?? 'default'; // 'default'
    const value = 0 ?? 'default';         // 0 (not 'default')
    const value = '' ?? 'default';        // '' (not 'default')
    
    // Logical assignment
    let a = null;
    a ??= 'default';  // a = 'default'
    
    let b = 5;
    b ??= 10;  // b = 5 (unchanged)
    
    let obj = { count: 0 };
    obj.count ||= 1;  // obj.count = 1
    obj.count &&= 2;  // obj.count = 2
    

    Performance Optimization

    // Debounce
    function debounce(fn, delay) {
      let timeoutId;
      return (...args) => {
        clearTimeout(timeoutId);
        timeoutId = setTimeout(() => fn(...args), delay);
      };
    }
    
    const searchDebounced = debounce(search, 300);
    
    // Throttle
    function throttle(fn, limit) {
      let inThrottle;
      return (...args) => {
        if (!inThrottle) {
          fn(...args);
          inThrottle = true;
          setTimeout(() => inThrottle = false, limit);
        }
      };
    }
    
    const scrollThrottled = throttle(handleScroll, 100);
    
    // Lazy evaluation
    function* lazyMap(iterable, transform) {
      for (const item of iterable) {
        yield transform(item);
      }
    }
    
    // Use only what you need
    const numbers = [1, 2, 3, 4, 5];
    const doubled = lazyMap(numbers, x => x * 2);
    const first = doubled.next().value;  // Only computes first value
    

    Best Practices

    1. Use const by default: Only use let when reassignment is needed
    2. Prefer arrow functions: Especially for callbacks
    3. Use template literals: Instead of string concatenation
    4. Destructure objects and arrays: For cleaner code
    5. Use async/await: Instead of Promise chains
    6. Avoid mutating data: Use spread operator and array methods
    7. Use optional chaining: Prevent "Cannot read property of undefined"
    8. Use nullish coalescing: For default values
    9. Prefer array methods: Over traditional loops
    10. Use modules: For better code organization
    11. Write pure functions: Easier to test and reason about
    12. Use meaningful variable names: Self-documenting code
    13. Keep functions small: Single responsibility principle
    14. Handle errors properly: Use try/catch with async/await
    15. Use strict mode: 'use strict' for better error catching

    Common Pitfalls

    1. this binding confusion: Use arrow functions or bind()
    2. Async/await without error handling: Always use try/catch
    3. Promise creation unnecessary: Don't wrap already async functions
    4. Mutation of objects: Use spread operator or Object.assign()
    5. Forgetting await: Async functions return promises
    6. Blocking event loop: Avoid synchronous operations
    7. Memory leaks: Clean up event listeners and timers
    8. Not handling promise rejections: Use catch() or try/catch

    Resources

    • MDN Web Docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript
    • JavaScript.info: https://javascript.info/
    • You Don't Know JS: https://github.com/getify/You-Dont-Know-JS
    • Eloquent JavaScript: https://eloquentjavascript.net/
    • ES6 Features: http://es6-features.org/
    Recommended Servers
    Vercel Grep
    Vercel Grep
    Svelte
    Svelte
    OpenZeppelin
    OpenZeppelin
    Repository
    microck/ordinary-claude-skills
    Files