Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
miles990 avatar

Design Patterns

  • 82 installs
  • 19 repo stars
  • Updated January 20, 2026
  • miles990/claude-software-skills

Helps with design & ui/ux tasks.

About

design-patterns is a Claude Code skill for design & ui/ux. It helps solo builders move faster with AI-assisted development.

  • design-patterns
  • Design & UI/UX
  • AI-coding skill

Design Patterns by the numbers

  • 82 all-time installs (skills.sh)
  • +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
  • Ranked #1,170 of 1,880 Design & UI/UX skills by installs in the Skillselion catalog
  • Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/miles990/claude-software-skills --skill design-patterns

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs82
repo stars19
Last updatedJanuary 20, 2026
Repositorymiles990/claude-software-skills

What it does

Helps with design & ui/ux tasks.

Files

SKILL.mdMarkdownGitHub ↗

Design Patterns

Overview

Reusable solutions to common software design problems. Understanding patterns helps you communicate design ideas effectively and avoid reinventing the wheel.

---

Creational Patterns

Factory Method

Purpose: Create objects without specifying exact class

// Abstract factory
interface PaymentProcessor {
  process(amount: number): Promise<Result>;
}

class StripeProcessor implements PaymentProcessor { /* ... */ }
class PayPalProcessor implements PaymentProcessor { /* ... */ }

function createProcessor(type: string): PaymentProcessor {
  switch (type) {
    case 'stripe': return new StripeProcessor();
    case 'paypal': return new PayPalProcessor();
    default: throw new Error(`Unknown processor: ${type}`);
  }
}

Builder

Purpose: Construct complex objects step by step

class QueryBuilder {
  private query: Query = {};

  select(...fields: string[]) {
    this.query.fields = fields;
    return this;
  }

  from(table: string) {
    this.query.table = table;
    return this;
  }

  where(condition: Condition) {
    this.query.conditions ??= [];
    this.query.conditions.push(condition);
    return this;
  }

  build(): string {
    return this.compile(this.query);
  }
}

// Usage
const sql = new QueryBuilder()
  .select('id', 'name')
  .from('users')
  .where({ age: { gte: 18 } })
  .build();

Singleton

Purpose: Ensure single instance (use sparingly)

// Modern approach: module-level instance
// database.ts
class Database {
  private constructor() {}

  private static instance: Database;

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

// Better: Dependency injection
class UserService {
  constructor(private db: Database) {}
}

---

Structural Patterns

Adapter

Purpose: Make incompatible interfaces work together

// Legacy API returns XML
interface LegacyAPI {
  getDataXML(): string;
}

// New code expects JSON
interface ModernAPI {
  getData(): object;
}

class APIAdapter implements ModernAPI {
  constructor(private legacy: LegacyAPI) {}

  getData(): object {
    const xml = this.legacy.getDataXML();
    return this.parseXML(xml);
  }

  private parseXML(xml: string): object {
    // Convert XML to object
  }
}

Decorator

Purpose: Add behavior without modifying original

// Base interface
interface DataSource {
  read(): string;
  write(data: string): void;
}

// Decorator adds encryption
class EncryptedDataSource implements DataSource {
  constructor(private wrapped: DataSource) {}

  read(): string {
    return this.decrypt(this.wrapped.read());
  }

  write(data: string): void {
    this.wrapped.write(this.encrypt(data));
  }
}

// Decorator adds compression
class CompressedDataSource implements DataSource {
  constructor(private wrapped: DataSource) {}
  // Similar pattern...
}

// Compose decorators
const source = new EncryptedDataSource(
  new CompressedDataSource(
    new FileDataSource('data.txt')
  )
);

Facade

Purpose: Simplify complex subsystem

// Complex subsystems
class VideoConverter { /* ... */ }
class AudioExtractor { /* ... */ }
class BitrateCalculator { /* ... */ }
class CodecFactory { /* ... */ }

// Simple facade
class VideoExporter {
  export(video: Video, format: Format): File {
    const codec = CodecFactory.getCodec(format);
    const bitrate = BitrateCalculator.optimal(video);
    const converter = new VideoConverter(codec, bitrate);
    const audio = AudioExtractor.extract(video);
    return converter.convert(video, audio);
  }
}

// Client only needs facade
const exporter = new VideoExporter();
const mp4 = exporter.export(video, 'mp4');

Proxy

Purpose: Control access to object

// Virtual proxy for lazy loading
class ImageProxy implements Image {
  private realImage: RealImage | null = null;

  constructor(private filename: string) {}

  display(): void {
    if (!this.realImage) {
      this.realImage = new RealImage(this.filename); // Expensive
    }
    this.realImage.display();
  }
}

// Protection proxy
class SecureDocumentProxy implements Document {
  constructor(
    private doc: Document,
    private user: User
  ) {}

  read(): string {
    if (!this.user.hasPermission('read')) {
      throw new Error('Access denied');
    }
    return this.doc.read();
  }
}

---

Behavioral Patterns

Observer

Purpose: Notify dependents of state changes

class EventEmitter<T extends Record<string, unknown>> {
  private listeners = new Map<keyof T, Set<Function>>();

  on<K extends keyof T>(event: K, callback: (data: T[K]) => void) {
    if (!this.listeners.has(event)) {
      this.listeners.set(event, new Set());
    }
    this.listeners.get(event)!.add(callback);

    // Return unsubscribe function
    return () => this.listeners.get(event)?.delete(callback);
  }

  emit<K extends keyof T>(event: K, data: T[K]) {
    this.listeners.get(event)?.forEach(cb => cb(data));
  }
}

// Usage
interface Events {
  userCreated: User;
  orderPlaced: Order;
}

const emitter = new EventEmitter<Events>();
emitter.on('userCreated', user => sendWelcomeEmail(user));

Strategy

Purpose: Interchange algorithms at runtime

interface CompressionStrategy {
  compress(data: Buffer): Buffer;
}

class ZipCompression implements CompressionStrategy {
  compress(data: Buffer): Buffer { /* ... */ }
}

class GzipCompression implements CompressionStrategy {
  compress(data: Buffer): Buffer { /* ... */ }
}

class FileCompressor {
  constructor(private strategy: CompressionStrategy) {}

  setStrategy(strategy: CompressionStrategy) {
    this.strategy = strategy;
  }

  compress(file: File): Buffer {
    return this.strategy.compress(file.data);
  }
}

Command

Purpose: Encapsulate actions as objects

interface Command {
  execute(): void;
  undo(): void;
}

class MoveCommand implements Command {
  private previousPosition: Position;

  constructor(
    private object: GameObject,
    private newPosition: Position
  ) {}

  execute() {
    this.previousPosition = this.object.position;
    this.object.position = this.newPosition;
  }

  undo() {
    this.object.position = this.previousPosition;
  }
}

class CommandHistory {
  private history: Command[] = [];
  private current = -1;

  execute(command: Command) {
    command.execute();
    this.history = this.history.slice(0, this.current + 1);
    this.history.push(command);
    this.current++;
  }

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

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

State

Purpose: Change behavior based on state

interface State {
  handle(context: Context): void;
}

class DraftState implements State {
  handle(context: Context) {
    console.log('Document is draft');
    // Can edit, save, submit for review
  }
}

class ReviewState implements State {
  handle(context: Context) {
    console.log('Document under review');
    // Can approve or reject
  }
}

class PublishedState implements State {
  handle(context: Context) {
    console.log('Document is published');
    // Read-only, can unpublish
  }
}

class Document {
  private state: State = new DraftState();

  setState(state: State) {
    this.state = state;
  }

  handle() {
    this.state.handle(this);
  }
}

---

Functional Patterns

Monad (Result/Option)

type Result<T, E> = { ok: true; value: T } | { ok: false; error: E };

function map<T, U, E>(
  result: Result<T, E>,
  fn: (value: T) => U
): Result<U, E> {
  return result.ok
    ? { ok: true, value: fn(result.value) }
    : result;
}

function flatMap<T, U, E>(
  result: Result<T, E>,
  fn: (value: T) => Result<U, E>
): Result<U, E> {
  return result.ok ? fn(result.value) : result;
}

// Usage - compose operations safely
const result = pipe(
  parseJSON(input),
  flatMap(validate),
  flatMap(save),
  map(formatResponse)
);

Pipeline / Middleware

type Middleware<T> = (context: T, next: () => Promise<void>) => Promise<void>;

class Pipeline<T> {
  private middlewares: Middleware<T>[] = [];

  use(middleware: Middleware<T>) {
    this.middlewares.push(middleware);
    return this;
  }

  async execute(context: T) {
    let index = 0;

    const next = async (): Promise<void> => {
      if (index < this.middlewares.length) {
        const middleware = this.middlewares[index++];
        await middleware(context, next);
      }
    };

    await next();
  }
}

---

Anti-Patterns to Avoid

Anti-PatternProblemSolution
God ObjectOne class does everythingSplit into focused classes
Spaghetti CodeTangled dependenciesApply SRP, use modules
Golden HammerUsing one pattern everywhereChoose right pattern per problem
Premature OptimizationOptimizing before measuringProfile first, then optimize

---

Decision Guide

Need to create objects?
├── Complex construction → Builder
├── Family of related objects → Abstract Factory
├── Subclass decides type → Factory Method
└── Single instance → Singleton (rarely)

Need to structure objects?
├── Make incompatible interfaces work → Adapter
├── Add behavior dynamically → Decorator
├── Simplify complex system → Facade
└── Control access → Proxy

Need to manage behavior?
├── Notify on state change → Observer
├── Swap algorithms → Strategy
├── Encapsulate actions → Command
└── State-dependent behavior → State

Related Skills

  • [[architecture-patterns]] - Higher-level patterns
  • [[code-quality]] - When to apply patterns
  • [[refactoring]] - Introducing patterns to existing code

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.