How to Add Assets (Logos, Screenshots) to an OpenAI Plugin: Complete Guide

Place image files in your plugin's assets/ directory and reference them via relative paths in the composerIcon, logo, and screenshots fields of .codex-plugin/plugin.json to render branding in the Codex Marketplace.

The openai/plugins repository implements a declarative asset model that simplifies how you add assets (logos, screenshots) to a plugin. By placing visual resources in a standardized directory structure and declaring them in the plugin manifest, you ensure branding renders correctly in the marketplace UI without additional runtime configuration.

Asset Directory Structure

The plugin system expects static assets to reside in a specific location within your plugin's folder hierarchy.

The Assets Folder

Every plugin in the repository follows the convention of storing visual assets in a dedicated assets/ subdirectory. According to the source code structure, you must place logos, screenshots, SVGs, and PNGs inside plugins/<plugin-name>/assets/. The runtime serves these files directly to the UI when the plugin publishes to the Codex Marketplace.

For example, the Vercel plugin stores its branding images in plugins/vercel/assets/ and references them from the manifest file located at plugins/vercel/.codex-plugin/plugin.json.

Configuring the Plugin Manifest

The .codex-plugin/plugin.json manifest file controls how the marketplace displays your plugin's visual identity.

composerIcon and logo Fields

The manifest's interface object accepts two primary image fields:

  • composerIcon: Displays in the composer interface
  • logo: Represents the plugin in marketplace listings

Both fields require relative paths from the manifest file to the asset. As implemented in the Vercel plugin, the configuration looks like:

{
  "name": "vercel",
  "interface": {
    "displayName": "Vercel",
    "composerIcon": "./assets/logo-padded.png",
    "logo": "./assets/logo-padded.png"
  }
}

Screenshots Array

To showcase plugin functionality, include a screenshots array containing relative paths to PNG or JPG files:

{
  "interface": {
    "screenshots": [
      "./assets/screenshot-1.png",
      "./assets/screenshot-2.png"
    ]
  }
}

The marketplace renders these images in the plugin detail view automatically.

Skill-Level Asset References

When building UI components within individual skills, you may need to reference the same assets or additional static files.

Using staticFile() in Remotion

For video generation workflows or media-heavy skills, use the staticFile() helper to resolve asset URLs at runtime. As documented in plugins/remotion/skills/remotion/rules/images.md, import the helper from Remotion and reference files placed in the skill's public/ folder:

import { Img, staticFile } from "remotion"

export const Header = () => {
  return <Img src={staticFile("logo.svg")} style={{ width: 120 }} />
}

Place logo.svg in the skill's public/ directory to ensure it bundles correctly with the deployment.

Next.js and Vercel Integration

For web-based skills using Next.js, reference assets using standard public directory conventions. When the plugin builds, the assets/ folder copies into the deployment's public/ directory, making files accessible at root-relative paths:

export default function Home() {
  return <img src="/assets/logo.svg" alt="My logo" />
}

Complete Implementation Example

Follow this directory structure to ensure assets load correctly:

plugins/
└─ my-plugin/
   ├─ .codex-plugin/
   │  └─ plugin.json
   └─ assets/
      ├─ logo.svg
      ├─ screenshot-1.png
      └─ screenshot-2.png

Update plugin.json with relative references:

{
  "name": "my-plugin",
  "version": "0.1.0",
  "interface": {
    "displayName": "My Plugin",
    "composerIcon": "./assets/logo.svg",
    "logo": "./assets/logo.svg",
    "screenshots": [
      "./assets/screenshot-1.png",
      "./assets/screenshot-2.png"
    ]
  }
}

Because the manifest uses simple string paths, you can swap assets without modifying code; the marketplace UI updates automatically on the next refresh.

Summary

  • Store assets in plugins/<plugin-name>/assets/ to ensure they ship with your plugin bundle to the Codex Marketplace
  • Reference images in .codex-plugin/plugin.json using relative paths for composerIcon, logo, and the screenshots array
  • Use staticFile() when rendering assets inside Remotion-based skills from the public/ folder
  • Access assets in Next.js skills via root-relative paths like /assets/logo.svg after the build process copies the directory
  • Version control assets alongside code so they persist across marketplace installations

Frequently Asked Questions

What image formats does the OpenAI plugin system support?

The asset model accepts standard web formats including SVG, PNG, and JPG files. The manifest stores these as relative path strings, and the marketplace runtime serves them directly without transformation, so use optimized web-ready formats.

Can I change a plugin's logo without publishing a new version?

No, asset changes require a commit and publication because the files are version-controlled alongside the plugin code. The marketplace refreshes the UI only after the new bundle deploys, though the manifest structure allows you to swap filenames without changing code logic.

How do I reference the same logo in both the manifest and a skill's UI?

Place the image in the plugin's assets/ folder for manifest references, and copy or symlink it to the skill's public/ folder for runtime access. In Remotion skills, use staticFile("logo.svg"); in Next.js skills, use /assets/logo.svg after the build process copies files to the public directory.

Where does the Codex Marketplace look for plugin screenshots?

The marketplace reads the screenshots array in .codex-plugin/plugin.json, expecting relative paths like ./assets/screenshot-1.png. These paths resolve against the plugin root, so ensure screenshots reside in the assets/ directory or another location relative to the manifest file.

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 →