Skip to content

Plugins

EasyAdmin's plugin system lets external FiveM resources extend the UI at runtime — no code is compiled into EasyAdmin.

How It Works

  1. Your resource calls exports.EasyAdmin:RegisterPlugin(config) from Lua
  2. EasyAdmin stores the registration and syncs it to the NUI (React frontend)
  3. When an admin opens your plugin's page/tab/widget, the NUI triggers an event that your plugin listens for via AddEventHandler
  4. Your handler calls the cb callback with a schema tree — a declarative description of the UI using EasyAdmin's built-in components
  5. EasyAdmin renders the schema. When a button is clicked, the NUI routes to the matching event handler, which can return a new schema to re-render

Why events? FiveM exports cannot pass functions between resources. The config table works through exports, but handler functions must be registered via AddEventHandler so they stay in the plugin's own scope.

Plugins never ship React components or TypeScript. They compose UI from EasyAdmin's existing component palette (cards, stat cards, buttons, tables, charts, alerts, badges, icons, etc.).

Where to Start

What You Can Build

Contribution Where it appears
Nav items Sidebar entries that open a plugin page
Pages Full-page views in the main content area
Player tabs Tabs injected into the player detail page
Dashboard widgets Cards on the dashboard

Permissions

Plugins declare permissions in the RegisterPlugin config. EasyAdmin registers them server-side so they work with DoesPlayerHavePermission() and the admin session handshake:

1
2
3
4
5
exports.EasyAdmin:RegisterPlugin({
  id = 'my-plugin',
  permissions = { 'plugin.my-plugin', 'plugin.my-plugin.advanced' },
  -- ...
})

Grant the easyadmin.plugin.my-plugin ACE to admins who should see it. Gate individual tabs, nav items, or the entire plugin via the permission field.

See Custom Permissions for the full reference.