pluginagentmarketplace/custom-plugin-javascript · Archived

patterns

JavaScript design patterns and architectural best practices.

First seen Feb 7, 2026

Installation

$ npx skills add pluginagentmarketplace/custom-plugin-javascript --skill patterns

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from pluginagentmarketplace/custom-plugin-javascript · top by installs.

npx skills add pluginagentmarketplace/custom-plugin-javascript

Browse all from pluginagentmarketplace/custom-plugin-javascript

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 1
License LICENSE
Default branch main
Open issues 0
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 4,974 B
  • docs SUMMARY.md 76 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 4 installs

SKILL.md

JavaScript Patterns Skill

Quick Reference Card

Creational Patterns

Factory

function createUser(type) {
  const users = {
    admin: () => ({ role: 'admin', permissions: ['all'] }),
    user: () => ({ role: 'user', permissions: ['read'] })
  };
  return users[type]?.() ?? users.user();
}

Singleton

class Database {
  static #instance;

  static getInstance() {
    if (!Database.#instance) {
      Database.#instance = new Database();
    }
    return Database.#instance;
  }
}

Builder

class QueryBuilder {
  #query = { select: '*', from: '', where: [] };

  select(fields) { this.#query.select = fields; return this; }
  from(table) { this.#query.from = table; return this; }
  where(condition) { this.#query.where.push(condition); return this; }
  build() { return this.#query; }
}

new QueryBuilder()
  .select('name, email')
  .from('users')
  .where('active = true')
  .build();

Structural Patterns

Module

const Counter = (function() {
  let count = 0; // Private

  return {
    increment: () => ++count,
    decrement: () => --count,
    get: () => count
  };
})();

Facade

class ApiClient {
  async getUser(id) {
    const response = await fetch(`/api/users/${id}`);
    if (!response.ok) throw new Error('Failed');
    return response.json();
  }

  async updateUser(id, data) {
    return this.#request('PUT', `/api/users/${id}`, data);
  }

  #request(method, url, data) {
    return fetch(url, {
      method,
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data)
    }).then(r => r.json());
  }
}

Decorator

function withLogging(fn) {
  return function(...args) {
    console.log('Calling:', fn.name, args);
    const result = fn.apply(this, args);
    console.log('Result:', result);
    return result;
  };
}

const add = withLogging((a, b) => a + b);

Behavioral Patterns

Observer (Pub/Sub)

class EventEmitter {
  #events = new Map();

  on(event, handler) {
    if (!this.#events.has(event)) this.#events.set(event, []);
    this.#events.get(event).push(handler);
    return () => this.off(event, handler);
  }

  off(event, handler) {
    const handlers = this.#events.get(event) ?? [];
    this.#events.set(event, handlers.filter(h => h !== handler));
  }

  emit(event, data) {
    (this.#events.get(event) ?? []).forEach(h => h(data));
  }
}

Strategy

const validators = {
  email: (v) => /\S+@\S+/.test(v),
  phone: (v) => /^\d{10}$/.test(v),
  required: (v) => v?.trim().length > 0
};

function validate(value, rules) {
  return rules.every(rule => validators[rule]?.(value) ?? true);
}

validate('[email protected]', ['required', 'email']); // true

Command

class CommandManager {
  #history = [];
  #index = -1;

  execute(command) {
    command.execute();
    this.#history = this.#history.slice(0, this.#index + 1);
    this.#history.push(command);
    this.#index++;
  }

  undo() {
    if (this.#index >= 0) {
      this.#history[this.#index--].undo();
    }
  }

  redo() {
    if (this.#index < this.#history.length - 1) {
      this.#history[++this.#index].execute();
    }
  }
}

Modern Patterns

Composition

const withLogger = (obj) => ({
  ...obj,
  log: (msg) => console.log(`[${obj.name}] ${msg}`)
});

const withValidator = (obj) => ({
  ...obj,
  validate: () => !!obj.value
});

const field = withValidator(withLogger({ name: 'email', value: '' }));

Middleware

function createPipeline(...middlewares) {
  return (input) => middlewares.reduce(
    (acc, fn) => fn(acc),
    input
  );
}

const process = createPipeline(
  (x) => x.trim(),
  (x) => x.toLowerCase(),
  (x) => x.replace(/\s+/g, '-')
);

process('  Hello World  '); // 'hello-world'

Troubleshooting

When to Use

Pattern Use When
Factory Multiple similar objects
Singleton Single shared instance
Observer Event-driven communication
Strategy Swappable algorithms
Facade Complex subsystem

Anti-Patterns to Avoid

  • God objects (do everything)
  • Tight coupling
  • Callback hell
  • Magic numbers/strings
  • Premature optimization

Related

  • Agent 06: Modern ES6+ (detailed learning)
  • Skill: functions: Function patterns
  • Skill: modern-javascript: Classes