Xgenious/ docs

Plugin Development Guide

This guide is for developers who want to add a feature to Xilancer without editing core. It covers the framework contract, every hook and slot, plugin-owned MVC, security, testing, packaging, and migration from the old module layout.

The reference implementation is the framework version 1.0.0 shipped with Xilancer 4.3.0.

Read in this order

  1. Overview - the three layers, the invariants, and what a plugin can do.
  2. Creating a Plugin - scaffold a working plugin in ten minutes.
  3. Manifest Reference - every field in plugin.json, with validation rules.
  4. Lifecycle & Discovery - discovery, dependency ordering, validation, activation, boot, and failure isolation.
  5. Hooks, Slots & Registry - the full contract: filters, actions, slots, registry domains, and payload shapes.
  6. Routes, Views & Settings - plugin-owned MVC, storage, settings, and admin menus.
  7. Security & Best Practices - escaping, capabilities, secrets, SSRF, idempotency, and performance.
  8. Testing & Packaging - hermetic tests, the validator, zip layout, and release checks.
  9. Plugin Catalog - every shipped plugin, its hooks, tables, and permissions.
  10. Legacy Module Migration - move a module.json module into plugin.json without breaking old views or config.

The one-paragraph version

Core calls guarded plugin_*() helpers at seam points. The framework dispatches filters, actions, slots, and registry lookups to active plugins. A plugin is a directory with a plugin.json manifest and an entry class that implements PluginInterface and receives a PluginContext. Plugins are inactive by default; activation is stored outside core. A plugin never imports App\* or Modules\*; if it needs core data, core passes it through a seam.

Conventions used in this guide

  • core/ is the Laravel application.
  • plugins/ is the plugin root, a sibling of core/.
  • Code marked core-side is something the Xilancer team adds; plugin authors cannot add new seams from a plugin.
  • Code marked plugin-side is what you write.
  • All payloads are scalars and arrays. Models, requests, passwords, OTPs, and tokens are never passed.

What you cannot do

The framework is deliberately narrow. You cannot:

  • Add a new core seam from a plugin. Ask for one, or use an existing filter, action, slot, or registry.
  • Hook outbound mail. It has no central funnel.
  • Bypass validation with a *.create_data filter. Validation runs first; the filter enriches.
  • Change ownership, statuses, passwords, or flags through a data filter. The allow-list is re-asserted after your filter runs.
  • Hook subscription expiry. It is passive and has no transition.
  • Assume a model instance in a payload. You receive IDs and scalars.

Getting help

  • Read the Plugin Catalog for a plugin close to your feature.
  • Copy plugins/example-hello-world for the smallest working example.
  • Read plugins/HOOKS.md in the repository for the file-and-line host of every seam.
  • Run php core/artisan plugins list after every change.

Last updated: October 21, 2026

Still stuck?
Our support team is ready to help you get set up.
Get support