Where Are Static Assets Like Logos Stored for OpenAI Plugins?

Static assets for each OpenAI plugin are stored in a dedicated assets directory located at the root of that plugin's folder, with paths referenced in the plugin's plugin.json manifest file.

In the openai/plugins repository, every plugin maintains a self-contained structure that bundles code and media together. Each plugin directory contains an assets folder that houses all static resources—including logos, icons, and other media files—alongside a .codex-plugin/plugin.json manifest that defines how these resources are exposed.

The Plugin Assets Directory Structure

Every plugin in the repository follows a consistent filesystem pattern. The assets directory lives directly under the plugin's top-level folder, making resource paths predictable and portable.

For example, the Google Calendar plugin stores its visual resources in plugins/google-calendar/assets/, while the Gmail plugin uses plugins/gmail/assets/. This co-location ensures that static files are version-controlled alongside the plugin's logic, enabling atomic updates that bundle code changes with corresponding asset modifications.

The repository structure follows this pattern:

plugins/
├── google-calendar/
│   ├── assets/
│   │   ├── logo.png
│   │   └── icon.png
│   └── .codex-plugin/
│       └── plugin.json
├── gmail/
│   ├── assets/
│   │   └── gmail-small.svg
│   └── .codex-plugin/
│       └── plugin.json
└── linear/
    ├── assets/
    │   └── logo.svg
    └── .codex-plugin/
        └── plugin.json

How Manifest Files Reference Static Assets

The plugin.json manifest—located in each plugin's .codex-plugin/ subdirectory—contains specific keys that point to files within the local assets directory. These relative paths ensure that plugins remain portable across different hosting environments.

The primary manifest fields that consume static assets include:

  • logo_url: Points to the main logo displayed in the ChatGPT UI (e.g., plugins/google-calendar/assets/logo.png)
  • icon_url: References smaller thumbnails used in plugin listings (e.g., plugins/google-calendar/assets/icon.png)

Because these URLs are stored as relative paths in plugins/<plugin-name>/.codex-plugin/plugin.json, consumers must resolve them against the repository root or raw GitHub content base URL. This design keeps plugins self-contained while allowing flexible deployment strategies.

Accessing and Using Plugin Assets

When building integrations or documentation that reference plugin branding, you must construct the full URL by combining the base repository path with the relative asset location defined in the manifest.

Fetching Asset URLs Programmatically

To dynamically retrieve a plugin's logo from its manifest:

import fetch from 'node-fetch';

const BASE_URL = 'https://raw.githubusercontent.com/openai/plugins/main';
const manifestPath = 'plugins/google-calendar/.codex-plugin/plugin.json';

const manifest = await (await fetch(`${BASE_URL}/${manifestPath}`)).json();
const logoUrl = `${BASE_URL}/${manifest.logo_url}`;

console.log('Logo location:', logoUrl);
// Output: https://raw.githubusercontent.com/openai/plugins/main/plugins/google-calendar/assets/logo.png

Embedding Assets in HTML

For direct reference without JavaScript processing:

<img src="https://raw.githubusercontent.com/openai/plugins/main/plugins/gmail/assets/gmail-small.svg" 
     alt="Gmail plugin icon" 
     width="64" 
     height="64">

Adding New Assets to a Plugin

When contributing a new static resource to an existing plugin:

cd plugins/my-new-plugin
mkdir -p assets
cp /path/to/new-logo.png assets/

# Update the manifest to reference the new file

sed -i 's|"logo_url": ".*"|"logo_url": "assets/new-logo.png"|' .codex-plugin/plugin.json

git add assets/new-logo.png .codex-plugin/plugin.json
git commit -m "Add updated logo for My New Plugin"

Version Control and Plugin Isolation

The self-contained architecture ensures that each plugin's lifecycle remains independent. Because assets directories reside within individual plugin folders rather than a shared resource pool, modifying the Gmail plugin's icon in plugins/gmail/assets/ cannot inadvertently break the Linear plugin's branding in plugins/linear/assets/.

This isolation extends to the manifest files located in .codex-plugin/plugin.json. Each plugin defines its own asset mappings, preventing namespace collisions and simplifying rollback procedures. When a developer commits changes to plugins/clickup/assets/logo.svg, that change is scoped exclusively to the ClickUp plugin's history and deployment pipeline.

Summary

  • Location: Each plugin stores static assets in its own assets subdirectory (e.g., plugins/google-calendar/assets/).
  • Manifest reference: The .codex-plugin/plugin.json file uses relative paths in fields like logo_url and icon_url to point to these assets.
  • Path resolution: Full URLs require prepending the repository base path to the relative asset paths stored in manifests.
  • Isolation: Assets are version-controlled per-plugin, ensuring changes to one plugin's media do not affect others.

Frequently Asked Questions

Can I use external URLs for plugin logos instead of local assets?

While the manifest structure supports URL fields, the openai/plugins repository convention requires storing official logos locally in the plugin's assets directory. This ensures availability and version consistency. External URLs may break if third-party hosts change, whereas local assets in plugins/<name>/assets/ remain synchronized with the plugin code.

What file formats are supported for plugin icons?

The repository accepts standard web image formats including PNG, SVG, and JPEG. The Google Calendar plugin uses logo.png and icon.png, while the Linear plugin stores its branding as logo.svg. SVG is preferred for scalability, but raster formats are fully supported when transparency or photographic detail is required.

Modify the file in the plugin's assets directory (e.g., plugins/gmail/assets/logo.png) and commit the change. If the filename changes, update the corresponding field in plugins/gmail/.codex-plugin/plugin.json to reflect the new path. The self-contained structure ensures the update applies only to that specific plugin without side effects.

Are plugin assets shared across multiple plugins?

No. Each plugin maintains its own isolated assets folder. The Gmail plugin cannot reference files from plugins/google-calendar/assets/, and vice versa. This separation prevents cross-plugin dependencies and ensures that uninstalling or modifying one plugin never breaks another's visual assets.

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 →