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 directoryapps: "./.app.json"referencing external dependenciesinterfacemetadata 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 examplesagents/: Optional agent configurations (e.g.,openai.yaml)references/: Documentation or context filesassets/: Skill-specific resourcesscripts/: 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 definitionshooks.json: Lifecycle hook registrationsscripts/: Utility scripts beyond skill logicui/: 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
{
"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"
}
}
# Greet Skill
This skill prints a friendly greeting.
## Usage
`greet <name>`
## Example
`greet Alice` → *Hello, Alice!*
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.jsonthe single source of truth for metadata, versioning, and skill locations. - Isolate dependencies: Store third-party SDK configurations in optional
.app.jsonfiles to prevent version conflicts. - Organize skills discretely: Place capabilities in
skills/<skill>/folders with mandatorySKILL.mdfiles 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →