How to Organize a Plugin Repository Structure for Scalability: The OpenAI Approach

The OpenAI plugins repository achieves scalability through a deliberately flat but modular layout, where each plugin resides in an isolated subfolder with standardized manifest files, enabling independent versioning, parallel CI/CD pipelines, and seamless expansion to dozens of plugins.

Organizing a growing ecosystem of plugins requires architectural patterns that balance isolation with discoverability. The openai/plugins repository demonstrates how to organize plugin repository structure for scalability by enforcing strict conventions around directory hierarchy, metadata declarations, and skill payloads. This architecture ensures that adding new capabilities never creates cross-dependencies or maintenance bottlenecks, allowing the codebase to grow linearly without architectural drift.

The Flat Folder Architecture

The repository maintains a single top-level plugins/ directory where every plugin lives in its own subfolder (plugins/<plugin-name>/). This flat structure keeps the surface area small while allowing each plugin to evolve independently. The repository root contains a README.md that documents the overall organization, but all plugin-specific code, configuration, and assets remain isolated within their respective directories. Because each plugin is self-contained, continuous integration pipelines can run tests in parallel for each folder without cross-contamination.

Standardized Manifest Files

The Core Plugin Manifest

Every plugin must contain a .codex-plugin/plugin.json file that serves as the single source of truth for the plugin loader. This manifest declares the plugin's name, version, capabilities, and the location of the skill payload. The name field must match the folder name, and every change increments the version field, enabling automated publishing pipelines to detect updates without scanning the entire repository.

In plugins/figma/.codex-plugin/plugin.json, the manifest defines:

  • skills: "./skills/" pointing to the capabilities directory
  • apps: "./.app.json" referencing external dependencies
  • interface metadata including display names and logo paths

Dependency Isolation with .app.json

Many plugins rely on shared third-party integrations (e.g., the Figma API). The optional .app.json file at the plugin root declares these dependencies and isolates SDK versioning from the skill code. This separation prevents dependency conflicts between plugins and allows the Figma integration to update its client library without affecting other plugins in the repository.

Skill Payload Organization

Concrete capabilities live under the skills/ directory, with each skill occupying its own subfolder (e.g., skills/figma-use/). Every skill folder follows a consistent Codex skill layout containing:

  • SKILL.md: Human-readable description of inputs, behavior, and examples
  • agents/: Optional agent configurations (e.g., openai.yaml)
  • references/: Documentation or context files
  • assets/: Skill-specific resources
  • scripts/: Executable logic

This repeatable structure allows automated tooling to discover new capabilities by scanning for SKILL.md files, regardless of which plugin contains them.

Asset Management and Static Resources

Static resources such as icons and logos reside in a top-level assets/ directory within each plugin folder. The manifest references these via relative paths (e.g., "logo": "./assets/icon.png"), preventing duplication across skills and keeping the plugin.json concise. The Figma plugin, for instance, stores its logo-padded.png in plugins/figma/assets/ rather than embedding binary data in the manifest.

Optional Extensions for Advanced Use Cases

The architecture supports optional auxiliary directories that extend functionality without cluttering minimal plugins:

  • commands/: CLI command definitions
  • hooks.json: Lifecycle hook registrations
  • scripts/: Utility scripts beyond skill logic
  • ui/: Web interface components

These directories are never required for a functional plugin, maintaining a low base footprint while accommodating complex integrations when necessary.

Automated Scaffolding with Plugin Creator

To enforce conventions consistently, the repository includes a plugin-creator skill located at .agents/skills/plugin-creator/. This scaffolding tool generates a new plugin with the correct directory hierarchy, sample plugin.json, and placeholder SKILL.md files. Running the creator skill ensures that every new plugin adheres to the repository's scalable structure automatically, reducing onboarding friction and preventing structural drift.

CI/CD Scalability Through Isolation

Because each plugin is self-contained under plugins/<name>/, continuous integration systems can execute test suites in parallel without complex orchestration. Adding a new plugin requires only creating its folder and the two manifest files (.codex-plugin/plugin.json and optionally .app.json); no other part of the repository requires modification. This isolation eliminates merge conflicts between plugin teams and allows the repository to scale horizontally.

Minimal Plugin Example

The following structure demonstrates a minimal valid plugin named my-awesome-tool:

plugins/
└─ my-awesome-tool/
   ├─ .codex-plugin/
   │   └─ plugin.json          # Required manifest

   ├─ assets/
   │   └─ icon.png
   └─ skills/
       └─ greet/
           ├─ SKILL.md        # Skill description

           └─ scripts/
               └─ greet.py    # Implementation

plugin.json

{
  "name": "my-awesome-tool",
  "version": "1.0.0",
  "description": "A demonstration plugin showing how to greet a user.",
  "skills": "./skills/",
  "interface": {
    "displayName": "My Awesome Tool",
    "logo": "./assets/icon.png"
  }
}

SKILL.md


# Greet Skill

This skill prints a friendly greeting.

## Usage

`greet <name>`

## Example

`greet Alice`*Hello, Alice!*

greet.py

def run(name: str) -> str:
    """Return a friendly greeting."""
    return f"Hello, {name}!"

Summary

  • Use a flat structure: Place each plugin in plugins/<name>/ to maintain clear ownership boundaries and enable parallel processing.
  • Standardize manifests: Make .codex-plugin/plugin.json the single source of truth for metadata, versioning, and skill locations.
  • Isolate dependencies: Store third-party SDK configurations in optional .app.json files to prevent version conflicts.
  • Organize skills discretely: Place capabilities in skills/<skill>/ folders with mandatory SKILL.md files for automated discovery.
  • Centralize assets: Keep static resources in plugin-level assets/ directories referenced by relative paths.
  • Automate scaffolding: Leverage the .agents/skills/plugin-creator/ skill to generate consistent boilerplate for new plugins.

Frequently Asked Questions

What is the minimum required file structure for a plugin?

A valid plugin requires a directory under plugins/<name>/ containing at least a .codex-plugin/plugin.json manifest and one skill subfolder under skills/ containing a SKILL.md file. The plugin.json must declare the plugin name, version, and the relative path to the skills directory.

How does the repository handle external API dependencies?

External dependencies are declared in an optional .app.json file located at the plugin root, which the main manifest references via the apps field. This isolates third-party SDK versioning—such as the Figma API client—from the skill implementation code, preventing cross-plugin dependency conflicts.

Can a plugin exist without skill definitions?

No, the skills field in plugin.json is mandatory and must point to a directory containing at least one valid skill with a SKILL.md descriptor. However, auxiliary directories like commands/, ui/, or hooks.json are optional and only required for plugins exposing CLI commands, web interfaces, or lifecycle hooks.

How does the plugin-creator skill ensure repository consistency?

The .agents/skills/plugin-creator/ skill automatically generates the complete directory scaffold—including the plugin.json manifest, folder hierarchies, and sample SKILL.md templates—ensuring every new plugin follows the established conventions without manual configuration or structural errors.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →