Back to blog
tutorialpluginsdevelopmentextensibility

Building Custom Plugins for AuraBoot

AuraBoot Team|

A hands-on guide to building custom plugins for AuraBoot — from directory structure and model definitions to commands, pages, and deployment.

Building Custom Plugins for AuraBoot

AuraBoot's plugin system is the primary way to extend the platform. Whether you're adding a new business module, integrating a third-party service, or building an industry-specific solution, plugins provide a structured, portable, and versionable approach. This guide walks you through building one from scratch.

Plugin Architecture

A plugin is a directory containing JSON configuration files. The platform reads these files during import and creates all necessary database structures, permissions, menus, and page schemas automatically.

plugins/
  my-plugin/
    plugin.json          # Manifest
    config/
      models.json        # Data models
      fields.json        # Field definitions
      commands.json      # CRUD and custom operations
      pages.json         # Page layouts
      dicts.json         # Dictionary values
      menus.json         # Navigation entries
      permissions.json   # Access control
      roles.json         # Default role assignments
      bindings.json      # Model-field bindings
      i18n.json          # Translations

Step 1: Create the Manifest

Every plugin starts with plugin.json:

{
  "code": "asset-management",
  "name": "Asset Management",
  "version": "1.0.0",
  "description": "Track and manage company assets — equipment, software licenses, and facilities",
  "author": "Your Company",
  "category": "business",
  "dependencies": []
}

The code must be unique across your installation. Use dependencies to declare requirements on other plugins.

Step 2: Define Models

Models represent your business entities. In config/models.json:

[
  {
    "code": "asset",
    "name": "Asset",
    "tableName": "mt_asset",
    "displayField": "name",
    "description": "Physical or digital asset tracked by the organization"
  },
  {
    "code": "asset_assignment",
    "name": "Asset Assignment",
    "tableName": "mt_asset_assignment",
    "displayField": "asset_id",
    "description": "Records who has been assigned an asset and when"
  }
]

AuraBoot automatically creates the database tables with standard system fields (id, created_by, created_at, updated_at, tenant_id).

Step 3: Define Fields

Fields define the columns for each model. In config/fields.json:

[
  {
    "modelCode": "asset",
    "code": "name",
    "name": "Asset Name",
    "dataType": "TEXT",
    "required": true
  },
  {
    "modelCode": "asset",
    "code": "asset_code",
    "name": "Asset Code",
    "dataType": "TEXT",
    "required": true,
    "unique": true
  },
  {
    "modelCode": "asset",
    "code": "category",
    "name": "Category",
    "dataType": "DICT",
    "dictCode": "asset_category"
  },
  {
    "modelCode": "asset",
    "code": "status",
    "name": "Status",
    "dataType": "DICT",
    "dictCode": "asset_status"
  },
  {
    "modelCode": "asset",
    "code": "purchase_date",
    "name": "Purchase Date",
    "dataType": "DATE"
  },
  {
    "modelCode": "asset",
    "code": "purchase_price",
    "name": "Purchase Price",
    "dataType": "DECIMAL",
    "precision": 12,
    "scale": 2
  },
  {
    "modelCode": "asset",
    "code": "assigned_to",
    "name": "Assigned To",
    "dataType": "REFERENCE",
    "refModelCode": "employee"
  }
]

Supported Data Types

TypeUse Case
TEXTNames, descriptions, codes
INTEGERQuantities, counts
DECIMALPrices, measurements
BOOLEANFlags, toggles
DATECalendar dates
DATETIMETimestamps
DICTEnum-like values from dictionaries
REFERENCEForeign key to another model
RICHTEXTRich text content with HTML
FILEFile attachments

Step 4: Add Dictionaries

Dictionaries provide predefined values for DICT fields:

[
  {
    "code": "asset_category",
    "name": "Asset Category",
    "items": [
      { "value": "HARDWARE", "label": "Hardware", "sort": 1 },
      { "value": "SOFTWARE", "label": "Software License", "sort": 2 },
      { "value": "FURNITURE", "label": "Furniture", "sort": 3 },
      { "value": "VEHICLE", "label": "Vehicle", "sort": 4 }
    ]
  },
  {
    "code": "asset_status",
    "name": "Asset Status",
    "items": [
      { "value": "AVAILABLE", "label": "Available", "color": "#10B981" },
      { "value": "ASSIGNED", "label": "Assigned", "color": "#3B82F6" },
      { "value": "MAINTENANCE", "label": "In Maintenance", "color": "#F59E0B" },
      { "value": "RETIRED", "label": "Retired", "color": "#6B7280" }
    ]
  }
]

Step 5: Define Commands

Commands define the operations users can perform:

[
  {
    "modelCode": "asset",
    "code": "asset__create",
    "name": "Create Asset",
    "actionType": "CREATE",
    "triggerMode": "FORM"
  },
  {
    "modelCode": "asset",
    "code": "asset__update",
    "name": "Update Asset",
    "actionType": "UPDATE",
    "triggerMode": "FORM"
  },
  {
    "modelCode": "asset",
    "code": "asset__assign",
    "name": "Assign Asset",
    "actionType": "UPDATE",
    "triggerMode": "FORM",
    "fieldDefaults": { "status": "ASSIGNED" },
    "sideEffects": [
      {
        "type": "CREATE",
        "targetModel": "asset_assignment",
        "fieldMap": {
          "asset_id": "${recordId}",
          "assigned_to": "${assigned_to}",
          "assigned_date": "${NOW}"
        }
      }
    ]
  },
  {
    "modelCode": "asset",
    "code": "asset__retire",
    "name": "Retire Asset",
    "actionType": "UPDATE",
    "triggerMode": "DIRECT",
    "confirmMessage": "Are you sure you want to retire this asset?",
    "fieldDefaults": { "status": "RETIRED" }
  }
]

Notice how the "Assign Asset" command both updates the asset status and creates an assignment record through configuration, without a custom handler for this basic workflow.

Step 6: Design Pages

Pages define the UI layout:

[
  {
    "key": "assets",
    "title": "Assets",
    "modelCode": "asset",
    "schema": {
      "type": "list-detail",
      "list": {
        "columns": ["asset_code", "name", "category", "status", "assigned_to"],
        "filters": ["category", "status"],
        "actions": ["asset__create"]
      },
      "detail": {
        "sections": [
          { "title": "Asset Information", "fields": ["name", "asset_code", "category", "status"] },
          { "title": "Financial", "fields": ["purchase_date", "purchase_price"] },
          { "title": "Assignment", "fields": ["assigned_to"] }
        ],
        "actions": ["asset__update", "asset__assign", "asset__retire"]
      }
    }
  }
]

Step 7: Configure Menus and Permissions

Add navigation entries and default permissions:

// menus.json
[
  { "code": "assets", "name": "Assets", "type": "DIRECTORY", "icon": "Box", "sort": 200 },
  { "code": "asset_list", "name": "Asset List", "type": "PAGE", "parentCode": "assets", "path": "/meta/assets", "sort": 1 }
]

// permissions.json
[
  { "code": "asset:view", "name": "View Assets" },
  { "code": "asset:create", "name": "Create Assets" },
  { "code": "asset:edit", "name": "Edit Assets" },
  { "code": "asset:delete", "name": "Delete Assets" }
]

Step 8: Import and Test

Import your plugin:

auraboot plugin import plugins/asset-management/

The platform will:

  1. Validate all JSON files against schemas
  2. Create database tables for new models
  3. Register fields, commands, and pages
  4. Create permissions and assign them to admin roles
  5. Add menus to the sidebar

Advanced: Plugin Layering

Plugins can extend other plugins. An industry-specific plugin can add fields to a generic model:

{
  "modelCode": "asset",
  "code": "calibration_date",
  "name": "Last Calibration Date",
  "dataType": "DATE",
  "description": "Manufacturing-specific: last equipment calibration"
}

This field is added to the asset model defined in the base plugin, without modifying the base plugin's files.

Conclusion

AuraBoot's plugin system turns repeated application structure into configuration. Define your models, fields, commands, and pages in JSON, import the plugin, and you get a working business module with CRUD, permissions, audit trails, and API access. Custom code stays available for the parts that need it.

Explore the full plugin development guide in our documentation or browse existing plugins for inspiration in the Plugin Ecosystem.