# Publishing a plugin package `package.json` here is **strict JSON with no comments**, because Node, bun, npm, and every bundler parse it with a strict parser. Copy it as-is and delete the entrypoints you do not implement. Guidance lives in this file rather than in comments inside the manifest. Source: (Publish) ## Entrypoints ```json title="package.json" { "name": "opencode-acme-plugin", "version": "1.0.0", "type": "module", "exports": { ".": "./src/index.ts", "./rpc": "./src/rpc.ts", "./tui": "./src/tui.tsx" }, "dependencies": { "@opencode/plugin": "latest" } } ``` | Export | Needed for | Documented on | | ------ | ---------- | ------------- | | `.` | a server plugin | | | `./rpc` | publishing a shared RPC contract others can import without loading your implementation. The docs call this export **optional**. | | | `./tui` | the TUI plugin. Exporting it makes the CLI load the plugin automatically when the package is listed in `opencode.json(c)`. **Do not also add the package to `cli.json`** — the CLI gets the active plugin list from the server. | and | ## Effect plugin The documented manifest puts `effect` in `peerDependencies`, not `dependencies`: ```json { "dependencies": { "@opencode/plugin": "latest" }, "peerDependencies": { "effect": ">=4.0.0-rc.112" } } ``` Do **not** bundle `effect`. OpenCode provides `effect`, `effect/*`, and `@opencode/plugin` at runtime and redirects imports — including from your `node_modules` — to the host instance, so fibers, loggers, and `Schema` parsers share one runtime copy. If you bundle, mark `effect` and `effect/*` external. The same Effect page also says to install `effect` and `@opencode/plugin` as peer/dev dependencies for local type-checking: ```sh bun add --peer @opencode/plugin effect ``` Plugins always execute against the host release's `effect`. Using APIs or module paths from another `effect` major (such as Effect 3) is not supported. Only public `effect` subpaths are provided; importing an `internal` module fails to load with an error naming the path. The compiled OpenCode binary omits the Scalar/Swagger UI assets used by Effect's HTTP API doc pages, so serving those from a plugin shows a notice. ## TUI plugin rendering JSX ```json { "peerDependencies": { "@opentui/core": ">=0.5.8", "@opentui/solid": ">=0.5.8", "solid-js": ">=1.9.0" } } ``` From . Confirm the version floors against that page before publishing; they are the kind of value that goes stale. ## Testing before publishing Test the **installed** package, not only a workspace-linked copy: ```sh bun pm pack bun add ./opencode-acme-plugin-1.0.0.tgz ``` Use versions compatible with the OpenCode release you target — check with `opencode --version`. If a release changes the plugin API, publish a compatible update rather than leaving an old contract in place.