# Design Patterns Used in Modly's Architecture: A Complete Technical Guide

> Explore Modly's architecture and discover the seven design patterns like Store Hook Plugin Mediator Facade Factory and Command that enable its modular reactive design for React and Electron.

- Repository: [lightningpixel/modly](https://github.com/lightningpixel/modly)
- Tags: architecture
- Published: 2026-08-19

---

**Modly combines seven distinct design patterns—Store (State Container), Hook-Based Observer, Plugin, Mediator, Facade, Factory, and Command—to create a modular, reactive architecture that separates state management, UI rendering, and platform-specific logic between the React frontend and Electron backend.**

The `lightningpixel/modly` repository demonstrates how modern desktop applications can implement clean architectural boundaries using well-established design patterns. By analyzing the source code, we can identify the specific **design patterns used in Modly's architecture** that enable its extensible plugin system and maintainable codebase.

## Store Pattern: Centralized State with Zustand

Modly implements the **Store (State-Container) Pattern** using Zustand to eliminate prop drilling and create a single source of truth. In [`src/shared/stores/extensionsStore.ts`](https://github.com/lightningpixel/modly/blob/main/src/shared/stores/extensionsStore.ts), the store centralizes mutable UI state including extension lists, loading flags, and installation progress. The companion [`appStore.ts`](https://github.com/lightningpixel/modly/blob/main/appStore.ts) manages global application state such as UI scaling factors, backend connection status, and error message queues.

Components interact with this state through the `useExtensionsStore` hook, which provides both read access and dispatch methods like `loadExtensions()` and `installFromGitHub()`.

## Observer Pattern: React Hooks as Reactive Subscribers

The **Hook-Based Observer Pattern** appears throughout `src/shared/hooks/*.ts`, particularly in [`useApi.ts`](https://github.com/lightningpixel/modly/blob/main/useApi.ts) and [`useGeneration.ts`](https://github.com/lightningpixel/modly/blob/main/useGeneration.ts). These hooks subscribe to Zustand stores and automatically trigger component re-renders when underlying state values change.

This implementation provides the benefits of the Observer pattern without explicit event emitters. When [`extensionsStore.ts`](https://github.com/lightningpixel/modly/blob/main/extensionsStore.ts) updates its installation progress, all subscribed components in [`src/areas/workflows/WorkflowsPage.tsx`](https://github.com/lightningpixel/modly/blob/main/src/areas/workflows/WorkflowsPage.tsx) receive the update simultaneously through their hook subscriptions.

## Plugin Pattern: Dynamic Extension Architecture

Modly treats external functionality as plugins through the **Plugin (Extension) Pattern**. The system discovers, installs, and manages extensions at runtime, with each extension conforming to a defined manifest located in [`src/shared/types/electron.d.ts`](https://github.com/lightningpixel/modly/blob/main/src/shared/types/electron.d.ts).

The [`extensionsStore.ts`](https://github.com/lightningpixel/modly/blob/main/extensionsStore.ts) file handles the complete lifecycle of these plugins, while the main process code under `electron/main/` loads and executes extension logic. This pattern allows third-party developers to extend Modly's capabilities without modifying the core application code or requiring recompilation.

## Mediator Pattern: IPC as Communication Bridge

The **Mediator Pattern** manifests in [`electron/main/ipc-handlers.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/ipc-handlers.ts), where a centralized IPC layer handles all communication between the renderer (React) and the backend (Python/OS). Rather than allowing direct coupling between UI components and platform-specific APIs, the mediator translates high-level calls like `window.electron.extensions.*` into concrete actions.

This decoupling ensures that components remain platform-agnostic. The mediator manages the complexity of Electron's main-renderer process boundaries, routing commands such as `extensions:installFromGitHub` through a single controlled channel.

## Facade Pattern: Simplified Application Entry

**Facade Pattern** implementation appears in [`src/App.tsx`](https://github.com/lightningpixel/modly/blob/main/src/App.tsx), which conceals complex initialization logic behind a concise JSX tree. The component orchestrates setup checks, update handling, and UI scaling initialization, presenting a simple entry point for the rest of the application.

By hiding the intricate startup sequence—including backend status checks and one-off event listeners—the facade reduces cognitive load for developers working on feature areas in `src/areas/*`.

## Factory Pattern: Consistent Extension Creation

Modly uses **Factory-Like Functions** in [`src/shared/stores/extensionsStore.ts`](https://github.com/lightningpixel/modly/blob/main/src/shared/stores/extensionsStore.ts) through the `installExtension` helper. This function creates a consistent installation workflow—handling progress updates, error states, and state mutations—for both GitHub-based and local installations.

By centralizing object creation logic, the pattern ensures that all extensions follow the same initialization protocol regardless of their source, returning standardized result objects with `success` and `error` properties.

## Command Pattern: CLI Action Dispatching

The Python CLI in [`tools/modly-cli/agent.py`](https://github.com/lightningpixel/modly/blob/main/tools/modly-cli/agent.py) implements the **Command Pattern**, parsing user inputs into discrete action objects like `workflow_start`, `ensure`, and `comfy`. These commands encapsulate both the action and its parameters, allowing the CLI to queue, execute, or retry operations independent of the UI state.

This architectural approach mirrors the command dispatching used in the Electron frontend, maintaining consistency across Modly's interface layers.

## Code Examples

### Observing the Extensions Store

```tsx
import { useExtensionsStore } from '@shared/stores/extensionsStore'

// Load all extensions on component mount
useEffect(() => {
  useExtensionsStore.getState().loadExtensions()
}, [])

// Install a new extension from a GitHub URL
const install = async (url: string) => {
  const { success, error } = await useExtensionsStore.getState().installFromGitHub(url)
  if (!success) console.error('Install failed:', error)
}

```

### Mediator Pattern in IPC Communication

```tsx
// Renderer side (React) subscribing to progress updates
window.electron.extensions.onInstallProgress((data) => {
  console.log('Progress:', data.percent)
})

// Main process side (Mediator) handling the request
ipcMain.handle('extensions:installFromGitHub', async (_, url: string) => {
  // Perform download, validation, and registration
  return { success: true, extensionId: id }
})

```

### Facade Initialization in App.tsx

```tsx
export default function App() {
  const { checkSetup, initApp, backendStatus } = useAppStore()
  
  useEffect(() => {
    checkSetup()
    // Additional one-off listeners for update handling
  }, [])
  
  // Returns simplified UI tree hiding complex initialization
  return <MainLayout />
}

```

## Summary

- **Store Pattern**: Zustand stores in [`src/shared/stores/extensionsStore.ts`](https://github.com/lightningpixel/modly/blob/main/src/shared/stores/extensionsStore.ts) and [`appStore.ts`](https://github.com/lightningpixel/modly/blob/main/appStore.ts) centralize all mutable application state
- **Observer Pattern**: React hooks in `src/shared/hooks/*.ts` subscribe to store changes and trigger automatic UI updates
- **Plugin Pattern**: Runtime extension loading via manifest definitions in [`src/shared/types/electron.d.ts`](https://github.com/lightningpixel/modly/blob/main/src/shared/types/electron.d.ts) and the extensions store
- **Mediator Pattern**: IPC handlers in [`electron/main/ipc-handlers.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/ipc-handlers.ts) decouple React components from Electron platform APIs
- **Facade Pattern**: [`src/App.tsx`](https://github.com/lightningpixel/modly/blob/main/src/App.tsx) hides complex startup logic behind a simplified component interface
- **Factory Pattern**: `installExtension` helpers create consistent initialization workflows for third-party extensions
- **Command Pattern**: Python CLI in [`tools/modly-cli/agent.py`](https://github.com/lightningpixel/modly/blob/main/tools/modly-cli/agent.py) encapsulates discrete actions as command objects

## Frequently Asked Questions

### How does Modly synchronize state between the React frontend and Electron backend?

Modly uses Zustand stores combined with React hooks as observers. When the main process updates extension status via IPC, the store mutations trigger hook-based re-renders in components like [`WorkflowsPage.tsx`](https://github.com/lightningpixel/modly/blob/main/WorkflowsPage.tsx), ensuring automatic synchronization without manual event listener management.

### What pattern enables Modly to support third-party extensions without recompiling?

The **Plugin Pattern** enables runtime extension loading. Extensions conform to a manifest defined in [`src/shared/types/electron.d.ts`](https://github.com/lightningpixel/modly/blob/main/src/shared/types/electron.d.ts) and are managed through [`extensionsStore.ts`](https://github.com/lightningpixel/modly/blob/main/extensionsStore.ts), allowing the application to discover, install, and execute functionality dynamically.

### Why does Modly route all native calls through IPC handlers instead of direct Electron API access?

The **Mediator Pattern** implemented in [`electron/main/ipc-handlers.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/ipc-handlers.ts) decouples the React frontend from Electron's platform APIs. This prevents renderer process components from directly accessing native resources, improving security and testability by centralizing all platform communication.

### How does the CLI architecture maintain consistency with the desktop application?

Both interfaces use command abstractions. The Python CLI in [`tools/modly-cli/agent.py`](https://github.com/lightningpixel/modly/blob/main/tools/modly-cli/agent.py) implements the **Command Pattern** to parse actions like `workflow_start`, while the Electron frontend dispatches comparable actions through the Mediator IPC layer, ensuring architectural parity across command-line and graphical interfaces.