# Plugins

> How FeatherPanel plugins work. Install from the marketplace, a file or a URL, manage settings and visibility, and the layout, conf.yml and entry class of a plugin.

Source: https://featherpanel.com/docs/plugins/

Plugins (also called addons) add backend routes, event handlers, cron jobs, CLI commands, database tables, frontend
pages, sidebar entries and dashboard widgets to the panel without patching its code.

## Install a plugin

Open **Admin > Plugins**. You can:

- browse and install from the online registry (FeatherCloud marketplace), search by tag and see popular packages,
- upload an `.fpa` package,
- install from a URL.

Before installing from the registry the panel checks the package's requirements. After install you can change the
plugin's settings, hide its frontend pages from some users, limit its server sidebar entries to certain spells,
export it as a package, resync its file links or uninstall it. Each action needs `admin.plugins.view` or
`admin.plugins.manage`.

> [!WARNING]
> A plugin runs PHP inside the panel with full access to its database. Install only plugins you trust.

## Anatomy of a plugin

A plugin is a directory in `backend/storage/addons/` named after its identifier:

```text
demoshowcase/
├── conf.yml
├── DemoShowcase.php
└── Frontend/
    ├── sidebar.json
    ├── widgets.json
    └── Components/demoshowcase/dist/*.html
```

### conf.yml

```yaml
plugin:
  name: DemoStatus
  identifier: demostatus
  description: 'Status showcase'
  flags:
    - hasEvents
  version: 1.0.0
  target: v2
  author:
    - Your Name
  icon: 'https://example.com/icon.png'
  requiredConfigs: {}
  dependencies:
    - php=8.3
    - php-ext=pdo
config: {}
```

| Key | Notes |
|-----|-------|
| `name`, `identifier`, `description`, `version`, `target`, `icon` | Required strings. The identifier may only contain letters, digits and `_`. |
| `flags` | Required list. Allowed: `hasInstallScript`, `hasRemovalScript`, `hasUpdateScript`, `developerIgnoreInstallScript`, `developerEscalateInstallScript`, `userEscalateInstallScript`, `hasEvents`. |
| `author` | Required list of names. |
| `dependencies` | Required list. Entries are `php=`, `php-ext=`, `composer=` or `plugin=`. The plugin does not load if one is missing. |
| `requiredConfigs` | Required. Settings the admin must fill in before the plugin works. |
| `plugin_cloud_id`, `minimum_panel_version`, `maximum_panel_version` | Optional. |

### Entry class

The entry class lives in the namespace `App\Addons\<identifier>`, has the same name as `plugin.name`, and implements
`App\Plugins\AppPlugin`:

```php
<?php

namespace App\Addons\demostatus;

use App\Plugins\AppPlugin;
use App\Plugins\PluginEvents;

class DemoStatus implements AppPlugin
{
    public static function processEvents(PluginEvents $event): void
    {
        // Subscribe to panel events here.
    }

    public static function pluginInstall(): void
    {
    }

    public static function pluginUninstall(): void
    {
    }
}
```

An optional `pluginUpdate(?string $oldVersion, ?string $newVersion)` method runs on updates. If the name, class and
namespace do not match, the panel looks for a single `AppPlugin` class in the plugin root, and skips the plugin with a
log entry when it finds none.

### Other directories

| Directory | Purpose |
|-----------|---------|
| `Routes/` | Backend API routes |
| `Commands/` | Commands added to the panel CLI |
| `Migrations/` | SQL migrations for the plugin's tables |
| `Cron/` | Jobs picked up by the cron runner, see [Cron and workers](https://featherpanel.com/docs/panel/cron-and-workers) |
| `Frontend/sidebar.json` | Pages in the `client`, `admin` and `server` sidebars |
| `Frontend/widgets.json` | Widgets placed on panel pages |
| `Frontend/Components/` | Built HTML for those pages and widgets, loaded in an iframe |

## Develop a plugin

Read these in order the first time, then use them as a reference:

| Step | Page |
| --- | --- |
| 1. Build a working plugin in a few minutes | [Build your first plugin](https://featherpanel.com/docs/plugins/quick-start/) |
| 2. Learn the folder layout | [Plugin structure](https://featherpanel.com/docs/plugins/getting-started/) |
| 3. Describe the plugin | [Manifest (conf.yml)](https://featherpanel.com/docs/plugins/manifest/) and [Settings](https://featherpanel.com/docs/plugins/settings/) |
| 4. Run code when things happen | [Lifecycle and events](https://featherpanel.com/docs/plugins/lifecycle-and-events/) and the [event reference](https://featherpanel.com/docs/plugins/events/) |
| 5. Add an API | [Routes and permissions](https://featherpanel.com/docs/plugins/routes-and-permissions/) and [Middleware and router hooks](https://featherpanel.com/docs/plugins/middleware-and-hooks/) |
| 6. Add pages and widgets | [Frontend and Power SDK](https://featherpanel.com/docs/plugins/frontend/), [Widget slots](https://featherpanel.com/docs/plugins/widgets/) and [Themes and UI packs](https://featherpanel.com/docs/plugins/themes/) |
| 7. Store data | [Migrations and storage](https://featherpanel.com/docs/plugins/database/) |
| 8. Run background work | [Cron jobs and CLI commands](https://featherpanel.com/docs/plugins/cron-and-commands/) |
| 9. Ship it | [Packaging and publishing](https://featherpanel.com/docs/plugins/packaging-and-publishing/) |
| When something breaks | [Debugging plugins](https://featherpanel.com/docs/plugins/debugging/) and the [Plugin FAQ](https://featherpanel.com/docs/plugins/faq/) |

[Examples](https://featherpanel.com/docs/plugins/examples/) has complete plugins to copy from. The panel also ships its own developer docs,
[icanhasfeatherpanel](https://featherpanel.com/docs/plugins/icanhasfeatherpanel/), at `/icanhasfeatherpanel/` on every panel.

## Reference

- [Plugin events](https://featherpanel.com/docs/plugins/events): every event you can subscribe to.
- [Widgets](https://featherpanel.com/docs/plugins/widgets): pages and slots where widgets can appear.
- [API reference](https://featherpanel.com/docs/api/reference): the routes your frontend code can call.

## Frequently asked questions

### Where are plugins stored?

In backend/storage/addons/<identifier>. In the Docker backend container that is /var/www/html/storage/addons, backed by the featherpanel_addons volume, so plugins survive container updates.

### What is an .fpa file?

The package format for FeatherPanel addons, a zip archive that may be password protected. Marketplace downloads and exports use it, and the admin area can install one from an upload or a URL.
