What Is the .difypkg Format? Internal Structure and Repackaging Guide

The .difypkg format is a standard ZIP archive that bundles a Dify plugin's manifest, source code, and Python wheel dependencies into a single offline-installable package.

The Dify platform distributes plugins as self-contained .difypkg files. According to the junjiem/dify-plugin-repackaging source code, this format enables portable distribution by embedding all third-party dependencies directly within the archive, eliminating the need for external network access during installation.

What Is a .difypkg File?

A .difypkg file is nothing more than a renamed ZIP archive that follows a specific internal layout expected by the Dify plugin runtime. When you upload a .difypkg to Dify, the platform extracts this archive, reads the plugin metadata, and installs the bundled Python packages from the embedded wheels/ directory rather than downloading them from PyPI.

This design guarantees offline installation capability. By pre-downloading all required binary wheels and patching requirements.txt to use local paths, the repackaging script ensures the plugin installs reliably in air-gapped environments or networks with restricted egress.

Internal Structure of a .difypkg Archive

When you inspect a .difypkg using standard ZIP tools, you will find the following predictable layout:

your-plugin-1.2.3.difypkg   (ZIP archive)

├─ plugin.yaml              ← Plugin manifest (name, version, author)
├─ requirements.txt         ← Python dependencies (patched for offline use)
├─ wheels/                  ← Pre-downloaded wheel files (*.whl)
│   ├─ requests-2.31.0-py3-none-any.whl
│   └─ numpy-1.24.0-cp39-cp39-manylinux2014_x86_64.whl
├─ src/                     ← Plugin source code (Python package)
│   ├─ __init__.py
│   └─ … (module files)
├─ .difyignore              ← Files to exclude during upload (optional)
└─ README, LICENSE, etc.

The Plugin Manifest (plugin.yaml)

The file plugin.yaml (or occasionally plugin.json) serves as the entry point Dify reads to discover the plugin's metadata. It declares the plugin's unique identifier, version, author information, and runtime configuration. Without this file at the archive root, Dify cannot recognize or load the package.

Offline Dependencies (requirements.txt and wheels/)

The requirements.txt file located at the archive root controls dependency resolution. After repackaging, this file always begins with the directive:

--no-index --find-links=./wheels/

This line instructs pip to install packages exclusively from the local wheels/ directory, bypassing PyPI entirely. The wheels/ folder contains all binary wheel files (.whl) required by the plugin, including platform-specific compiled extensions for Linux, macOS, or Windows.

Source Code and Assets (src/ and .difyignore)

The src/ directory contains the actual Python implementation of the plugin. Any importable package layout works here as long as the entry points declared in plugin.yaml resolve correctly. The optional .difyignore file functions like .gitignore, specifying patterns for files and directories that Dify should exclude when processing the plugin upload.

How the Repackaging Script Modifies .difypkg

The plugin_repackaging.sh script in the junjiem/dify-plugin-repackaging repository automates the process of converting a standard Dify plugin into an offline-capable package. The workflow performs five distinct operations on the original .difypkg:

  1. Extract the original archive using unzip -o ${PACKAGE_PATH} -d ${CURR_DIR}/${PACKAGE_NAME} to create a working directory with the standard layout.

  2. Download dependencies by executing pip download … -d ./wheels to fetch every wheel specified in the original requirements.txt into a new wheels/ subdirectory.

  3. Patch requirements.txt using sed -i '1i\--no-index --find-links=./wheels/' requirements.txt (on Linux) to insert the offline-install directive at the top of the file, ensuring the plugin uses bundled wheels exclusively.

  4. Make the binary executable with chmod 755 ${CURR_DIR}/${CMD_NAME} on the dify-plugin-<os>-<arch> binary, which is required for the final packaging step.

  5. Re-package the directory by calling ${CMD_NAME} plugin package ${CURR_DIR}/${PACKAGE_NAME} -o ${CURR_DIR}/${PACKAGE_NAME}-${PACKAGE_SUFFIX}.difypkg --max-size 5120. This invokes the Dify-plugin CLI to rebuild the ZIP archive with the embedded wheels and modified requirements, producing the final offline-ready .difypkg.

Why Dify Uses the ZIP Format

The choice of ZIP as the container format provides three critical advantages for the Dify ecosystem:

  • Portability: A single file can be uploaded via Dify's web UI, REST API, or command-line interface without complex streaming or multi-part uploads.
  • Offline installation: By bundling wheels inside the archive, plugins install successfully in environments without internet access or behind strict corporate firewalls.
  • Integrity verification: Dify can compute cryptographic hashes of the entire archive before extraction, enabling signature verification and tamper detection prior to installation.

Inspecting and Creating .difypkg Files Manually

Because .difypkg files are standard ZIP archives, you can manipulate them using common command-line tools without specialized software.

To inspect the contents of any .difypkg:

unzip -l my-plugin-0.1.0.difypkg

To manually create a .difypkg from scratch:

mkdir myplugin && cd myplugin

# Create plugin.yaml, src/, requirements.txt, etc.

zip -r ../my-plugin-0.1.0.difypkg .

Note that for production use, you should use the official dify-plugin binary with the plugin package command (as shown in the repackaging script) to ensure the archive meets Dify's size limits and validation requirements.

Summary

  • .difypkg is a ZIP archive containing a Dify plugin's manifest, source code, and dependencies.
  • The wheels/ directory contains pre-downloaded Python packages, making the plugin offline-installable.
  • requirements.txt must start with --no-index --find-links=./wheels/ to force local wheel installation.
  • The repackaging script extracts the original package, downloads wheels, patches the requirements file, and re-zips the contents using the dify-plugin CLI.
  • Manual inspection is possible using standard unzip commands since the format follows standard ZIP specifications.

Frequently Asked Questions

How do I open or inspect a .difypkg file?

Use any standard ZIP utility. Run unzip -l filename.difypkg to list contents without extracting, or unzip filename.difypkg -d ./output to extract the archive to a specific directory. The format contains no encryption or compression beyond standard DEFLATE.

What happens if the wheels/ directory is missing from a .difypkg?

Without the wheels/ directory and the corresponding --no-index --find-links=./wheels/ line in requirements.txt, Dify will attempt to download dependencies from PyPI during installation. This fails in offline environments and may introduce version conflicts if PyPI packages differ from those tested during development.

Can I manually edit files inside a .difypkg without the repackaging script?

Yes. Extract the archive with unzip, modify the files (such as updating plugin.yaml or adding assets), then repackage with zip -r. However, if you need to add offline wheel support, you must manually run pip download to populate wheels/ and edit requirements.txt to include the local find-links directive before rezipping.

What is the maximum size for a .difypkg file?

According to the junjiem/dify-plugin-repackaging implementation, the dify-plugin CLI enforces a maximum package size of 5120 MB (5 GB) when using the --max-size 5120 flag during the plugin package command. Exceeding this limit requires removing unnecessary assets or splitting functionality into multiple plugins.

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 →