This guide uses
bun as the package manager, which is the preferred tool for ElizaOS development. Bun provides faster installation times and built-in TypeScript support.Table of Contents
- Introduction
- Quick Start: Scaffolding Plugins with CLI
- Plugin Architecture Overview
- Core Plugin Components
- Advanced: Creating Plugins Manually
- Plugin Types and Patterns
- Advanced Configuration
- Testing Strategies
- Security Best Practices
- Publishing and Distribution
- Reference Examples
Introduction
ElizaOS plugins are modular extensions that enhance AI agents with new capabilities, integrations, and behaviors. The plugin system follows a consistent architecture that enables:- Modularity: Add or remove functionality without modifying core code
- Reusability: Share plugins across different agents
- Type Safety: Full TypeScript support for robust development
- Flexibility: Support for various plugin types (platform, LLM, DeFi, etc.)
What Can Plugins Do?
- Platform Integrations: Connect to Discord, Telegram, Slack, Twitter, etc.
- LLM Providers: Integrate different AI models (OpenAI, Anthropic, Google, etc.)
- Blockchain/DeFi: Execute transactions, manage wallets, interact with smart contracts
- Data Sources: Connect to databases, APIs, or external services
- Custom Actions: Define new agent behaviors and capabilities
Quick Start: Scaffolding Plugins with CLI
The easiest way to create a new plugin is using the ElizaOS CLI, which provides interactive scaffolding with pre-configured templates. This is the recommended approach for most developers.Using elizaos create
The CLI offers two plugin templates to get you started quickly:
-
Quick Plugin (Backend Only) - Simple backend-only plugin without frontend
- Perfect for: API integrations, blockchain actions, data providers
- Includes: Basic plugin structure, actions, providers, services
- No frontend components or UI routes
-
Full Plugin (with Frontend) - Complete plugin with React frontend and API routes
- Perfect for: Plugins that need web UI, dashboards, or visual components
- Includes: Everything from Quick Plugin + React frontend, Vite setup, API routes
- Tailwind CSS pre-configured for styling
Quick Plugin Structure
After runningelizaos create and selecting “Quick Plugin”, you’ll get:
Full Plugin Structure
Selecting “Full Plugin” adds frontend capabilities:After Scaffolding
Once your plugin is created:- ✅ Proper TypeScript configuration
- ✅ Build setup with tsup (and Vite for full plugins)
- ✅ Example action and provider to extend
- ✅ Integration with
@elizaos/core - ✅ Development scripts ready to use
- ✅ Basic tests structure
Using Your Plugin in Projects
Plugins don’t necessarily need to be in the ElizaOS monorepo. You have two options for using your plugin in a project:Option 1: Plugin Inside the Monorepo
If you’re developing your plugin within the ElizaOS monorepo (in thepackages/ directory), you need to add it as a workspace dependency:
- Add your plugin to the root
package.jsonas a workspace dependency:
-
Run
bun installin the root directory to link the workspace dependency - Use the plugin in your project:
Option 2: Plugin Outside the Monorepo
If you’re creating a plugin outside of the ElizaOS monorepo (recommended for most users), usebun link:
- In your plugin directory, build and link it:
- In your project directory (e.g., using project-starter), link the plugin:
- Add the plugin to your project’s
package.jsondependencies:
- Use the plugin in your project:
When using
bun link, remember to rebuild your plugin (bun run build) after making changes for them to be reflected in your project.Plugin Architecture Overview
Plugin Interface
Every plugin must implement the corePlugin interface:
Directory Structure
Standard plugin structure:Core Plugin Components
1. Services
Services manage stateful connections and provide core functionality. They are singleton instances that persist throughout the agent’s lifecycle.Service Lifecycle Patterns
Services have a specific lifecycle that plugins must respect:1. Delayed Initialization
Sometimes services need to wait for other services or perform startup tasks:2. Actions
Actions are the heart of what your agent can DO. They’re intelligent, context-aware operations that can make decisions, interact with services, and chain together for complex workflows.Quick Reference
| Component | Purpose | Required | Returns |
|---|---|---|---|
name | Unique identifier | ✅ | - |
description | Help LLM understand when to use | ✅ | - |
similes | Alternative names for fuzzy matching | ❌ | - |
validate | Check if action can run | ✅ | Promise<boolean> |
handler | Execute the action logic | ✅ | Promise<ActionResult> |
examples | Teach LLM through scenarios | ✅ | - |
- Actions MUST return
ActionResultwithsuccessfield - Actions receive composed state from providers
- Actions can chain together, passing values through state
- Actions can use callbacks for intermediate responses
- Actions are selected by the LLM based on validation and examples
Action Anatomy
Real-World Action Patterns
1. Decision-Making Actions
Actions can use the LLM to make intelligent decisions based on context:2. Multi-Target Actions
Actions can handle complex targeting and routing:3. Stateful Reply Action
The simplest yet most important action - generating contextual responses:4. Permission-Based Actions
Actions that modify system state with permission checks:Action Best Practices
-
Always Return ActionResult
-
Use Callbacks for User Feedback
-
Chain Actions with Context
-
Validate Thoughtfully
-
Write Teaching Examples
Understanding ActionResult
TheActionResult interface is crucial for action interoperability:
- State Propagation: Values from one action flow to the next
- Error Handling: Consistent error reporting across all actions
- Logging: Structured data for debugging and analytics
- Action Chaining: Success/failure determines flow control
Action Execution Lifecycle
Advanced Action Techniques
Dynamic Action Registration
Conditional Action Chains
Action Composition
Self-Modifying Actions
Testing Actions
Actions should be thoroughly tested to ensure they behave correctly in various scenarios:E2E Testing Actions
For integration testing with a live runtime:3. Providers
Providers supply contextual information to the agent’s state before it makes decisions. They act as the agent’s “senses”, gathering relevant data that helps the LLM understand the current context.Provider Properties
name(required): Unique identifier for the providerdescription(optional): Human-readable description of what the provider doesdynamic(optional, default: false): If true, the provider is not included in default state composition and must be explicitly requestedposition(optional, default: 0): Controls execution order. Lower numbers execute first. Can be negative for early executionprivate(optional, default: false): If true, the provider is excluded from regular provider lists and must be explicitly included
Provider Execution Flow
- Providers are executed during
runtime.composeState() - By default, all non-private, non-dynamic providers are included
- Providers are sorted by position and executed in order
- Results are aggregated into a unified state object
- The composed state is passed to actions and the LLM for decision-making
Common Provider Patterns
Recent Messages Provider (position: 100)4. Evaluators
Evaluators run after the agent generates a response, allowing for analysis, learning, and side effects. They use the same handler pattern as actions but run post-response.Common Evaluator Patterns
Fact Extraction EvaluatorUnderstanding the Agent Lifecycle: Providers, Actions, and Evaluators
When an agent receives a message, components execute in this order:-
Providers gather context by calling
runtime.composeState()- Non-private, non-dynamic providers run automatically
- Sorted by position (lower numbers first)
- Results aggregated into state object
-
Actions are validated and presented to the LLM
- The actions provider lists available actions
- LLM decides which actions to execute
- Actions execute with the composed state
-
Evaluators run after response generation
- Process the response for insights
- Can store memories, log events, or trigger follow-ups
- Use
alwaysRun: trueto run even without a response
Accessing Provider Data in Actions
Actions receive the composed state containing all provider data. Here’s how to access it:Custom Provider Inclusion
To include specific providers when composing state:5. Model Handlers (LLM Plugins)
For LLM plugins, implement model handlers for different model types:6. HTTP Routes and API Endpoints
Plugins can expose HTTP endpoints for webhooks, APIs, or web interfaces. Routes are defined using theRoute type and exported as part of the plugin:
Response Helpers
Create consistent API responses:Authentication Patterns
Implement authentication in route handlers:File Upload Support
Handle multipart form data:Advanced: Creating Plugins Manually
For developers working within the ElizaOS monorepo or those who need complete control over their plugin structure, you can create plugins manually. This approach is useful when:- Contributing directly to the ElizaOS monorepo
- Creating highly customized plugin structures
- Integrating with existing codebases
- Learning the internals of plugin architecture
Step 1: Set Up the Project
Step 2: Configure package.json
Step 3: Create TypeScript Configuration
Step 4: Implement the Plugin
Plugin Types and Patterns
Plugin Dependencies and Priority
Plugins can declare dependencies on other plugins and control their loading order:Checking for Optional Dependencies
Platform Plugins
Platform plugins connect agents to communication platforms:LLM Plugins
LLM plugins integrate different AI model providers:Event Handling
Plugins can register event handlers to react to system events:DeFi Plugins
DeFi plugins enable blockchain interactions:Advanced Configuration
Configuration Hierarchy
ElizaOS follows a specific hierarchy for configuration resolution. Understanding this is critical for proper plugin behavior:Init-time vs Runtime Configuration
During plugin initialization, configuration access is different:Configuration Validation
Use Zod for runtime validation:agentConfig in package.json
Declare plugin parameters:Testing Strategies
Bun provides a built-in test runner that’s fast and compatible with Jest-like syntax. No need for additional testing frameworks.Unit Tests
Test individual components:Integration Tests
Test component interactions:Test Suite Implementation
Include tests in your plugin:Security Best Practices
1. Credential Management
2. Input Validation
3. Rate Limiting
4. Error Handling
Publishing and Distribution
For detailed information on publishing your plugin to npm and the ElizaOS registry, see our Plugin Publishing Guide.Quick Reference
The Plugin Publishing Guide covers the complete process including:
- Pre-publication validation
- npm authentication
- GitHub repository setup
- Registry PR submission
- Post-publication updates
Reference Examples
Minimal Plugin
Complete Templates
- Quick Start Templates: Use
elizaos createfor instant plugin scaffolding with pre-configured TypeScript, build tools, and example components
Common Patterns and Utilities
Retry Logic
Troubleshooting
Common Issues
- Plugin not loading: Check that the plugin is properly exported and listed in the agent’s plugins array
- Configuration errors: Verify all required settings are provided
- Type errors: Ensure @elizaos/core version matches other plugins
- Runtime errors: Check service initialization and error handling
Debug Tips
Bun-Specific Tips
When developing plugins with Bun:- Fast Installation: Bun’s package installation is significantly faster than npm
- Built-in TypeScript: No need for separate TypeScript compilation during development
- Native Test Runner: Use
bun testfor running tests without additional setup (no vitest needed) - Workspace Support: Bun handles monorepo workspaces efficiently
- Lock File: Bun uses
bun.lockb(binary format) for faster dependency resolution
Bun Test Features
Bun’s built-in test runner provides:- Jest-compatible API (
describe,it,expect,mock) - Built-in mocking with
mock()from ‘bun:test’ - Fast execution with no compilation step
- Coverage reports with
--coverageflag - Watch mode with
--watchflag - Snapshot testing support
Test File Conventions
Bun automatically discovers test files matching these patterns:*.test.tsor*.test.js*.spec.tsor*.spec.js- Files in
__tests__/directories - Files in
test/ortests/directories
Useful Bun Commands for Plugin Development
Best Practices Summary
- Architecture: Follow the standard plugin structure
- Type Safety: Use TypeScript strictly
- Error Handling: Always handle errors gracefully
- Configuration: Use runtime.getSetting() for all config
- Testing: Write comprehensive unit and integration tests
- Security: Never hardcode sensitive data
- Documentation: Provide clear usage examples
- Performance: Implement caching and rate limiting
- Logging: Use appropriate log levels
- Versioning: Follow semantic versioning
Getting Help
- Documentation: Check the main ElizaOS docs
- Examples: Study existing plugins in
packages/ - Community: Join the ElizaOS Discord
- Issues: Report bugs on GitHub

