open-wa
DocsPublishing a Plugin

Publishing a Plugin

How to package, version, and share your plugin with the community.

Publishing a Plugin

Package your plugin as an npm module so users can install it and load it from their open-wa configuration.

How to Share a Plugin

The workflow is:

  1. Build your plugin as an npm package
  2. Publish it to npm (or a private registry)
  3. Users install it with npm install or pnpm add
  4. Users load it via the plugins array in wa.config.js

Package Structure

package.json

{
  "name": "@myorg/my-plugin",
  "version": "1.0.0",
  "description": "A plugin that does X",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "exports": {
    ".": {
      "import": "./dist/index.js",
      "types": "./dist/index.d.ts"
    }
  },
  "files": [
    "dist"
  ],
  "peerDependencies": {
    "@open-wa/plugin-sdk": ">=5.0.0 <6.0.0"
  },
  "scripts": {
    "build": "tsc",
    "prepublishOnly": "npm run build"
  }
}

Key Fields

  • name: Use a scoped name such as @myorg/my-plugin to reduce naming collisions.
  • main: Set the package entry point for tools that read this legacy field.
  • exports: Declare the ESM entry point and type declarations; add a require entry if you support CommonJS consumers.
  • types: Point TypeScript users to the generated declarations.
  • files: Publish only the files users need, such as dist.
  • peerDependencies: Declare the SDK versions your plugin supports.

TypeScript Compilation

Compile your plugin before publishing:

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "declaration": true,
    "outDir": "dist",
    "rootDir": "src",
    "strict": true,
    "esModuleInterop": true
  },
  "include": ["src"]
}

Versioning

Semantic Versioning

Follow semver (MAJOR.MINOR.PATCH):

  • MAJOR: Breaking changes, such as removing a hook or changing a required config field.
  • MINOR: Backward-compatible features, such as adding an optional config field.
  • PATCH: Backward-compatible fixes.

Compatibility with open-wa Versions

Note which versions of open-wa your plugin is compatible with:

{
  "peerDependencies": {
    "@open-wa/plugin-sdk": ">=5.0.0 <6.0.0"
  },
  "engines": {
    "node": ">=22.21.1"
  }
}

Communicating Breaking Changes

For a major release, include migration instructions in the README and changelog. If you plan to remove a feature, give users a deprecation period where practical.

Telling Users How to Load It

Installation

npm install @myorg/my-plugin
# or
pnpm add @myorg/my-plugin

Configuration

Document the exact wa.config.mjs entries users need:

// wa.config.mjs
export default {
  plugins: [
    '@myorg/my-plugin',
  ],
  pluginConfig: {
    'my-plugin': {
      // Document each field here
      apiUrl: 'https://api.example.com',
      apiKey: process.env.MY_PLUGIN_API_KEY,
      enabled: true,
    },
  },
};

Use the package name in plugins; the pluginConfig key must match the plugin's meta.name.

Documenting Your Plugin

README Template

The plugin README must include:

# @myorg/my-plugin

Brief description of what the plugin does.

## Installation

```bash
npm install @myorg/my-plugin
```

## Configuration

Add to your `wa.config.mjs`:

```js
export default {
  plugins: ['@myorg/my-plugin'],
  pluginConfig: {
    'my-plugin': {
      // necessary: Description
      apiKey: process.env.MY_PLUGIN_API_KEY,
      // optional: Description (default: value)
      optionName: 'default',
    },
  },
};
```

### Configuration Options

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| apiKey | string | Yes | - | Your API key |
| optionName | string | No | "default" | Description |

## Features

- Feature 1
- Feature 2

## Troubleshooting

### Common issue 1
Solution...

### Common issue 2
Solution...

Check the published package locally

Load a local package build

Before publishing to npm, test locally:

// wa.config.mjs
export default {
  plugins: [
    new URL('./path/to/my-plugin/dist/index.js', import.meta.url).href,
  ],
  pluginConfig: {
    'my-plugin': {
      // test config
    },
  },
};

Use a named session

Use a named session while trying the plugin:

npx @open-wa/wa-automate@5.1.0 --config ./wa.config.mjs --session-id plugin-test --host 127.0.0.1 --port 8080

Multi-Session Compatibility

If your plugin stores session-specific data, run two named sessions and verify each plugin instance reads and writes data for its own session.

Was this helpful?

Your answer includes the page path and docs version.

On this page