How to Handle Plugin Dependencies and External Resources in OpenAI Plugins

You handle plugin dependencies and external resources by declaring runtime packages in skill-specific package.json or pyproject.toml files, binding external services through .app.json manifests, and injecting secrets via environment variables documented in reference markdown.

The OpenAI plugins repository implements a multi-layered architecture for isolating and managing dependencies across different programming languages and external services. Each plugin combines manifest metadata with skill-specific code packages, requiring precise configuration in files like plugins/figma/skills/figma-use/package.json and plugins/figma/.app.json to ensure reproducible execution. Understanding how to properly handle plugin dependencies and external resources is critical for maintaining secure, portable implementations that run reliably across different environments.

Understanding the Dependency Architecture

The repository organizes dependency management into three distinct layers that separate plugin identity from runtime requirements.

Plugin Manifest and App Bindings

At the root level, plugins/figma/.codex-plugin/plugin.json declares the plugin's identity and entry points for the Codex system. Adjacent to this, the plugins/figma/.app.json file contains the critical apps mapping that links the plugin to cloud-hosted integrations:

{
  "apps": {
    "zoominfo": {
      "id": "asdk_app_698a340b9230819188ba5a5eea79022d"
    }
  }
}

According to the source code, this id is read-only and tells Codex which remote service to target when a skill triggers an API call. Changing it requires registering a new integration.

Skill-Level Package Files

Individual skills define their own runtime dependencies through language-specific package files. The skill runner installs only these declared packages, keeping execution isolated from the host environment. For example, plugins/figma/skills/figma-use/package.json contains:

{
  "dependencies": {
    "@figma/plugin-typings": "^1.58.0",
    "axios": "^1.7.2"
  },
  "devDependencies": {
    "typescript": "^5.4.5"
  }
}

Only the dependencies section is installed at execution time; devDependencies are ignored to maintain lean containers.

Declaring Package-Level Dependencies

Different languages follow specific patterns for dependency declaration within the OpenAI plugins framework.

Managing npm Dependencies

When adding Node.js packages to a skill, modify the local package.json within the skill directory:

cd plugins/figma/skills/figma-use
npm install [email protected] --save

The resulting package.json entry ensures the runner automatically installs lodash when the skill executes, without requiring manual npm install on the host system.

Configuring Python Dependencies

For Python skills, the repository prefers pyproject.toml over requirements.txt for version pinning and optional extras support. As implemented in plugins/temporal/skills/temporal-developer/references/python/pyproject.toml:

[project]
name = "temporal-developer"
version = "0.1.0"
dependencies = [
    "temporalio>=1.6.0",
    "pydantic>=2.5.0"
]

This format supports exact version constraints and dependency groups that requirements.txt cannot express.

Handling External Service Integrations

Beyond code packages, plugins frequently depend on external APIs and cloud resources that require specific configuration patterns.

Binding Service IDs

External integrations are referenced through the .app.json file rather than hardcoded in skill logic. The apps object maps service names to integration IDs, as shown in plugins/zoominfo/.app.json. When a skill invokes an API, Codex resolves this ID to locate the correct remote service endpoint.

Documenting Required Environment Variables

API keys and secrets must never be hard-coded. Instead, skills read from environment variables and document requirements in reference files like plugins/render/skills/render-deploy/references/error-patterns.md. A typical implementation validates presence before use:

const apiKey = process.env.RENDER_API_KEY;
if (!apiKey) {
  throw new Error(
    "Missing RENDER_API_KEY – see docs at " +
    "https://github.com/openai/plugins/blob/main/plugins/render/skills/render-deploy/references/error-patterns.md"
  );
}

This pattern ensures clear error messages that link directly to setup documentation.

Managing Conditional and Optional Dependencies

Skills may require heavy optional libraries that should not slow down every execution. The repository implements conditional loading patterns as shown in plugins/zoom/skills/video-sdk/react-native/examples/setup-guide.md:

if (process.env.USE_NATIVE_SDK) {
  const nativeSdk = require('@zoom/native-sdk');
}

This guards against unnecessary installations and improves cold start performance by importing heavy native bindings only when explicitly requested.

Resolving Version Conflicts and Peer Dependencies

When dependencies conflict, reference documentation provides specific resolution strategies. The plugins/vercel/skills/workflow/SKILL.md file recommends handling peer dependency conflicts with:

npm install --legacy-peer-deps

Or installing compatible versions simultaneously:

npm install react@18 @workflow/ai@latest

Testing dependency failures locally by unsetting environment variables verifies that error messages correctly point to relevant reference documentation.

Summary

  • Declare runtime packages in skill-specific package.json or pyproject.toml files, keeping devDependencies separate.
  • Bind external services through .app.json configuration files using read-only integration IDs rather than hardcoded URLs.
  • Inject secrets via environment variables and document requirements in references/*.md files for clear error messaging.
  • Guard optional imports behind feature flags to avoid unnecessary container bloat.
  • Pin exact versions in pyproject.toml or package.json to prevent silent breaking changes.

Frequently Asked Questions

How do I add a new npm dependency to an existing plugin skill?

Navigate to the specific skill directory (e.g., plugins/figma/skills/figma-use/) and run npm install <package> --save. The skill runner automatically installs dependencies listed in the local package.json when executing the skill, without requiring manual installation on the host machine.

What is the difference between .app.json and plugin.json in the OpenAI plugins repository?

The .codex-plugin/plugin.json file declares the plugin's identity, version, and entry points for the Codex system, while .app.json contains the apps mapping that links the plugin to external cloud integrations via service IDs. Codex reads the plugin manifest first to locate skills, then resolves external API calls using the integration IDs stored in the app binding file.

How should I handle missing API keys or external service credentials?

Never hard-code credentials in source files. Instead, read values from environment variables at runtime and validate their presence before use. When a required variable is missing, throw an error that references the specific documentation file in your skill's references/ directory, such as plugins/render/skills/render-deploy/references/error-patterns.md.

Why does the repository prefer pyproject.toml over requirements.txt for Python dependencies?

The pyproject.toml format supports exact version pinning, optional dependency extras, and modern Python packaging standards that requirements.txt cannot express. This ensures reproducible builds and clearer dependency resolution across different execution environments.

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 →