# How to Develop a New Extension for Modly: A Complete Guide

> Learn to develop a new Modly extension. Create a GitHub repo with a manifest file and entry script, then install it easily via the Models tab. Get started today.

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

---

**You develop a Modly extension by creating a self-contained GitHub repository with a [`manifest.json`](https://github.com/lightningpixel/modly/blob/main/manifest.json) file and an entry script—JavaScript for process extensions or Python for model extensions—then installing it via the Models tab using the repository URL.**

Modly’s plugin architecture allows developers to extend the application’s capabilities by adding custom **process** or **model** extensions that integrate directly into the visual workflow editor. The core application discovers these extensions at runtime by cloning repositories into the local extensions directory and validating their manifests against a strict schema.

## Extension Types and Architecture

Modly supports two distinct extension types, each serving different purposes in the workflow pipeline.

### Process Extensions

**Process extensions** handle data transformation and manipulation within workflows. These execute JavaScript or TypeScript code to receive input from previous nodes, perform computations, and return results to downstream nodes. The backend loads these via the IPC bridge defined in [`electron/preload/electron-api.ts`](https://github.com/lightningpixel/modly/blob/main/electron/preload/electron-api.ts), specifically through the `extensions.runProcess` method.

### Model Extensions

**Model extensions** provide AI-powered generation capabilities, typically involving Python-based machine learning models. These require a [`generator.py`](https://github.com/lightningpixel/modly/blob/main/generator.py) file containing a class that inherits from Modly’s `BaseGenerator` interface. The class specified in the manifest’s `generator_class` field is instantiated by the backend to process inputs and return generated assets like 3D meshes.

## Creating the Extension Repository Structure

Every Modly extension must follow a specific repository layout to pass validation and load correctly.

### The manifest.json Schema

The **[`manifest.json`](https://github.com/lightningpixel/modly/blob/main/manifest.json)** file in your repository root defines the extension’s metadata and entry points. According to the validation logic in [`electron/main/extension-install-utils.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-install-utils.ts) (specifically the `validateInstallManifest` function), the manifest must include these required fields:

```json
{
  "id": "my-awesome-extension",
  "type": "process",
  "entry": "processor.js",
  "generator_class": "MyGenerator",
  "nodes": [{ "id": "my-node" }]
}

```

- **`id`**: A unique identifier across all installed extensions
- **`type`**: Either `"process"` or `"model"`, determining the validation path
- **`entry`**: The executable file path (defaults to [`processor.js`](https://github.com/lightningpixel/modly/blob/main/processor.js))
- **`generator_class`**: Required only for model extensions; specifies the Python class name to instantiate
- **`nodes`**: An array defining the node types this extension contributes to the workflow editor

### Repository Layout Requirements

For **process extensions**, your repository must contain:

- [`manifest.json`](https://github.com/lightningpixel/modly/blob/main/manifest.json) with `"type": "process"`
- The entry JavaScript file specified in the `entry` field

For **model extensions**, your repository must contain:

- [`manifest.json`](https://github.com/lightningpixel/modly/blob/main/manifest.json) with `"type": "model"`
- A [`generator.py`](https://github.com/lightningpixel/modly/blob/main/generator.py) file containing the generator class
- The `generator_class` field matching the class name in [`generator.py`](https://github.com/lightningpixel/modly/blob/main/generator.py)

## Implementing Process Extensions

Process extensions export an async function named `run` that receives input data and parameters from the workflow node.

Create a [`processor.js`](https://github.com/lightningpixel/modly/blob/main/processor.js) file implementing this signature:

```javascript
// processor.js – minimal process extension
export async function run(input, params) {
  // input: data from previous node (e.g., image buffer)
  // params: node-specific configuration values
  const result = await performTransformation(input, params);
  return { text: result.summary };
}

```

The return object’s shape must match the expectations of **`workflowRunStore`**, which processes the result and passes it to subsequent nodes. The function runs inside the Electron main process via the IPC bridge exposed in [`electron/preload/electron-api.ts`](https://github.com/lightningpixel/modly/blob/main/electron/preload/electron-api.ts), allowing access to Node.js APIs and external libraries.

## Implementing Model Extensions

Model extensions require Python code that implements the `BaseGenerator` interface from the `modly_api` package.

Create a [`generator.py`](https://github.com/lightningpixel/modly/blob/main/generator.py) file with a class matching your `generator_class` manifest field:

```python

# generator.py – minimal model extension

from modly_api import BaseGenerator

class MyGenerator(BaseGenerator):
    def generate(self, image_path: str) -> str:
        # Process the input image with your ML model

        mesh_path = run_inference_and_export_glb(image_path)
        return mesh_path

```

The backend validates that [`generator.py`](https://github.com/lightningpixel/modly/blob/main/generator.py) exists during installation (checked in [`extension-install-utils.ts`](https://github.com/lightningpixel/modly/blob/main/extension-install-utils.ts)) and dynamically imports the specified class. The `generate` method receives the input file path and must return the path to a generated asset (typically a `.glb` mesh file).

## Installing and Testing Your Extension

### Local Development Testing

To test your extension before publishing:

1. Clone your extension repository into the Modly extensions directory at `$HOME/.modly/extensions`
2. Launch Modly in development mode: `npm run dev`
3. Open the **Workflow** editor and add a node corresponding to your extension type
4. Select your extension from the node-type dropdown
5. Execute the workflow and monitor the console or UI logs (accessible at `extensions/errors`) for validation messages

### Installing from GitHub

Once tested, push your repository to GitHub. Users (or yourself on other machines) can install it via the UI:

1. Open Modly and navigate to the **Models** tab
2. Click **Install from GitHub**
3. Paste the HTTPS URL of your extension repository
4. Modly clones the repo, validates the [`manifest.json`](https://github.com/lightningpixel/modly/blob/main/manifest.json), compiles the entry file if necessary, and registers the extension

The installation process uses the methods exposed through [`electron/preload/electron-api.ts`](https://github.com/lightningpixel/modly/blob/main/electron/preload/electron-api.ts), including `extensions.installFromGitHub` and `extensions.reload`.

## Summary

- Modly extensions are self-contained GitHub repositories with a mandatory [`manifest.json`](https://github.com/lightningpixel/modly/blob/main/manifest.json) file validated by [`electron/main/extension-install-utils.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-install-utils.ts)
- **Process extensions** use JavaScript entry files exporting a `run(input, params)` function and integrate via `workflowRunStore`
- **Model extensions** use Python classes inheriting from `BaseGenerator` with a `generate()` method, specified via the `generator_class` manifest field
- Extensions install into `$HOME/.modly/extensions` and are discovered at runtime by the IPC bridge in [`electron/preload/electron-api.ts`](https://github.com/lightningpixel/modly/blob/main/electron/preload/electron-api.ts)
- Testing locally requires cloning to the extensions folder and running Modly in development mode

## Frequently Asked Questions

### What file structure is required for a Modly extension?

A valid extension requires a [`manifest.json`](https://github.com/lightningpixel/modly/blob/main/manifest.json) in the repository root plus an entry file appropriate to the type. Process extensions need a JavaScript file (default [`processor.js`](https://github.com/lightningpixel/modly/blob/main/processor.js)) exporting a `run` function, while model extensions require a [`generator.py`](https://github.com/lightningpixel/modly/blob/main/generator.py) containing a class that extends `BaseGenerator`. The [`manifest.json`](https://github.com/lightningpixel/modly/blob/main/manifest.json) must declare all required fields including `id`, `type`, and either `entry` or `generator_class` depending on the extension type.

### How does Modly validate extension manifests?

The `validateInstallManifest` function in [`electron/main/extension-install-utils.ts`](https://github.com/lightningpixel/modly/blob/main/electron/main/extension-install-utils.ts) validates every manifest against a strict schema. It checks that required fields exist, that the `type` is either `"process"` or `"model"`, and that appropriate complementary fields are present (e.g., `generator_class` for model types). Validation failures surface in the UI through the `extensions/errors` interface, preventing malformed extensions from loading.

### Can I use TypeScript for process extensions?

Yes, you can write process extensions in TypeScript. Modly compiles the entry file during installation if necessary. Ensure your [`manifest.json`](https://github.com/lightningpixel/modly/blob/main/manifest.json) points to the compiled JavaScript output or the TypeScript source if the build process handles transpilation. The exported `run` function must remain the default export regardless of the language used.

### How do I debug a Modly extension during development?

Debug by running Modly in development mode (`npm run dev`) with your extension cloned into `$HOME/.modly/extensions`. Use the **Workflow** editor to instantiate your node and execute test runs. Check the Electron console and the dedicated `extensions/errors` view in the UI for validation errors or runtime stack traces. You can reload extensions dynamically using the `extensions.reload` method exposed in [`electron/preload/electron-api.ts`](https://github.com/lightningpixel/modly/blob/main/electron/preload/electron-api.ts) without restarting the application.