Creating and Publishing Your Own Laravel Package

Creating and Publishing Your Own Laravel Package

Developing a Laravel package is an excellent way to modularize your code, share functionality across projects, or contribute to the Laravel ecosystem. This guide will walk you through the process of creating, developing, and publishing a Laravel package.

Setting Up Your Package

First, create a new directory for your package and initialize a composer.json file:

{
    "name": "your-vendor-name/your-package-name",
    "description": "A brief description of your package",
    "type": "library",
    "license": "MIT",
    "autoload": {
        "psr-4": {
            "YourVendorName\\YourPackageName\\": "src/"
        }
    },
    "require": {
        "php": "^8.0",
        "illuminate/support": "^8.0|^9.0|^10.0"
    },
    "extra": {
        "laravel": {
            "providers": [
                "YourVendorName\\YourPackageName\\YourPackageServiceProvider"
            ]
        }
    }
}

Creating a Service Provider

Create a service provider in src/YourPackageServiceProvider.php:

namespace YourVendorName\YourPackageName;

use Illuminate\Support\ServiceProvider;

class YourPackageServiceProvider extends ServiceProvider
{
    public function boot()
    {
        $this->loadRoutesFrom(__DIR__.'/../routes/web.php');
        $this->loadViewsFrom(__DIR__.'/../resources/views', 'your-package');
        $this->loadMigrationsFrom(__DIR__.'/../database/migrations');

        $this->publishes([
            __DIR__.'/../config/your-package.php' => config_path('your-package.php'),
        ], 'config');
    }

    public function register()
    {
        $this->mergeConfigFrom(
            __DIR__.'/../config/your-package.php', 'your-package'
        );
    }
}

Adding Functionality

Create your package's main class in src/YourPackage.php:

namespace YourVendorName\YourPackageName;

class YourPackage
{
    public function doSomething()
    {
        return 'Your package is working!';
    }
}

Package Discovery

Laravel's package discovery feature allows your package to be automatically registered. Ensure your composer.json includes:

"extra": {
    "laravel": {
        "providers": [
            "YourVendorName\\YourPackageName\\YourPackageServiceProvider"
        ]
    }
}

Testing Your Package

Create a tests directory and set up PHPUnit for testing:

namespace YourVendorName\YourPackageName\Tests;

use Orchestra\Testbench\TestCase;
use YourVendorName\YourPackageName\YourPackageServiceProvider;

class YourPackageTest extends TestCase
{
    protected function getPackageProviders($app)
    {
        return [YourPackageServiceProvider::class];
    }

    public function testPackage()
    {
        $this->assertTrue(true);
    }
}

Publishing Your Package

  1. Create a GitHub repository for your package.
  2. Push your code to the repository.
  3. Register on Packagist and submit your package.

Versioning

Use semantic versioning for your releases. Tag your releases in Git:

git tag -a v1.0.0 -m "First stable release"
git push --tags

Documentation

Create a README.md file with:

  • Installation instructions
  • Basic usage examples
  • Configuration details
  • Contribution guidelines

Real-World Example: Custom Logger Package

Let's create a simple custom logger package:

// src/CustomLogger.php
namespace YourVendorName\CustomLogger;

use Illuminate\Support\Facades\Log;

class CustomLogger
{
    public function log($message, $level = 'info')
    {
        Log::$level("[CustomLogger] $message");
    }
}

// src/CustomLoggerServiceProvider.php
namespace YourVendorName\CustomLogger;

use Illuminate\Support\ServiceProvider;

class CustomLoggerServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton('custom-logger', function ($app) {
            return new CustomLogger();
        });
    }
}

// In a Laravel application, after installing the package:
use YourVendorName\CustomLogger\Facades\CustomLogger;

CustomLogger::log('This is a custom log message', 'error');

Developing a Laravel package allows you to create reusable components that can be shared across projects or with the community. By following these steps and best practices, you can create well-structured, discoverable packages that extend Laravel's functionality and contribute to the ecosystem.

If this guide was helpful to you, subscribe to my daily newsletter and give me a follow on X/Twitter. It helps a lot!

Subscribe to Harris Raftopoulos

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe