Guides

Creating Your First Module

Beginner~10 min

Build a complete Meteorack module from scratch — manifest, entry point, services, and admin page.

Project Structure

Every module lives in wp-content/meteorack/modules/<slug>/. The Hub auto-discovers any folder with a valid module.json manifest. No registration code needed.

Directory structure
wp-content/meteorack/modules/my-module/
├── module.json          # Manifest
├── class-module.php     # Entry point
├── src/
│   └── class-handler.php
└── assets/
    └── admin.js

The Manifest

module.json declares your module's identity, PHP requirements, requested services, and admin integration. The Hub reads this before booting your code.

module.json
{
  "slug": "my-module",
  "name": "My Module",
  "version": "1.0.0",
  "entry": "class-module.php",
  "requires": {
    "php": "^8.2",
    "hub": "^1.0"
  },
  "services": ["settings", "logger", "cache"],
  "admin": {
    "page": true,
    "menu_title": "My Module"
  }
}

Entry Point

Your entry class implements ModuleInterface. The container auto-injects every service listed in module.json. The boot() method is your setup hook — register WordPress hooks, filters, and admin pages here.

class-module.php
<?php

declare(strict_types=1);

use Meteorack\SDK\Contracts\ModuleInterface;
use Meteorack\SDK\Contracts\SettingsInterface;
use Meteorack\SDK\Contracts\LoggerInterface;

class My_Module implements ModuleInterface {

    public function __construct(
        private readonly SettingsInterface $settings,
        private readonly LoggerInterface $logger,
    ) {}

    public function boot(): void {
        $this->logger->info('my-module.boot');
        add_action('admin_init', [$this, 'init']);
    }

    public function slug(): string {
        return 'my-module';
    }

    public function init(): void {
        $this->settings->register('my-module', [
            'enabled' => true,
        ]);
    }
}

Verify

Use WP-CLI to confirm your module is discovered and active. The Hub boots modules in isolation — a crash in your module won't affect others.

wp meteorack modules list

# Expected output:
# +-----------+---------+--------+
# | Module    | Version | Status |
# +-----------+---------+--------+
# | my-module | 1.0.0   | active |
# +-----------+---------+--------+