Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

davidxd33's avatar

Developing your packages in Laravel 5

I spent all day trying to get my packages flow going and after intense research and tests, I came up with a nice flexible way to develop packages without illuminate/workbench.

Setup your home for making packages (your workbench).


I created a directory called "packages" in my application root. Inside of the packages directory, follow the basic structure of any package (Vendor/Package/src).

It should look like so:

packages /
    Vendor /
        Package /
            src/

Setup your composer.json


Navigate to your package directory (Vendor/Package) and run:

composer init

It will ask a series of questions to generate your composer.json. You may include any required dependencies as you wish, we'll talk about autoloading them later.

Create your PackageServiceProvider


Like any old package, create your PackageServiceProvider inside of the src folder of your package. For more information on that, refer to the docs.

Autoload your package with PSR-4


Back to your project root, edit your composer.json to autoload your package namespace.

This is what your autoload section of composer.json should look like:

"autoload": {
    "psr-4": {
        "App\\": "app/",
        "Vendor\\Package\\": "packages/Vendor/Package/src"
    }
},

Create an application PackageServiceProvider


Here's the part that was tricky for me. When I wanted to use a third party in my package, I was getting a class not found exception. It was strange because I've already done my composer update. It's when I noticed that illuminate/workbench actually was requiring the composer autoload.php for all your packages. Now we're responsible for this.

Use a service provider to autoload all packages for you. Run:

php artisan make:provider PackageServiceProvider

Here's my provider (snipped for space): http://laravel.io/bin/RE24X

If you would like to skip making the PackageServiceProvider, you can manually require to autoload.php file from your package's boot() method.

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    require __DIR__ . '/../vendor/autoload.php';
}

Add your providers into your app config


Finally like all providers, add them to your config/app.php.

'providers' =>  [
    /*
    * Application Service Providers
    */
    'App\Providers\AppServiceProvider',
    'App\Providers\BusServiceProvider',
    'App\Providers\ConfigServiceProvider',
    'App\Providers\EventServiceProvider',
    'App\Providers\RouteServiceProvider',
    'App\Providers\RepositoryServiceProvider',

    'App\Providers\PackageServiceProvider',

    /*
    * Package Service Providers
    */
    'Vendor\Package\PackageServiceProvider',
]

That should be it. You now can develop your packages freely in laravel 5. If you encounter any errors or have a better solution, please tell me as I found this to be an easy way to develop packages in laravel 5.

Sources:

0 likes
30 replies
Moe's avatar

I realy appreciate your explanation.

@TaylorOtwell it should be nice to have some lessons about the package development.

23 likes
bbloom's avatar

I put my packages in a root folder called "packages", to avoid potential problems putting it in "vendor". Otherwise, similar set-up to what I'm doing.

davidxd33's avatar

@bbloom This method does put packages in a folder called "packages" in root. The vendor folder is for published packages.

Jeroen's avatar

Great! I was looking for this, thank you. You should make this a package. :D

stefr's avatar

@davidxd33 Maybe a newbie question: I made a package using this post. It works very well! However, if I would like to include this package in another project using composer it wil be installed in the /vendor/ directory. Now I'm confused. we've hardcoded some links to the /packages/ dir in the code for example:

    public function boot()
    {
            $this->loadAutoloader(base_path('packages'));
    }

and

"autoload": {
    "psr-4": {
        "App\\": "app/",
        "Vendor\\Package\\": "packages/Vendor/Package/src"
    }
},

So, is this package not intended to be reused?

stefr's avatar

@dberry Thanks for the reply. Can you tell me why it is bad to develop in the vendor directory? To me it looks like the easiest way right now.

dberry's avatar

The vendor directory should be packages that are managed by composer, it's not a development directory.

I mean technically you could, but it's frowned upon. Using something like Studio, it's extremely simple to do what you're wanting to do, it takes care of all of the auto-loading for you kind of like the old workbench feature in Laravel 4.2 did, with the exception of it's cleaner (as it's a composer plugin) and it's not Laravel specific (meaning it doesn't do the service provider, etc...)

tomicakorac's avatar

Guys, is there a way to register a package's service provider from within that package? I.e. can I register a service provider without adding it to the 'providers' array in 'config/app.php'?

MarkRedeman's avatar

@tomicakorac you can use $this->app->register('Acme\ServiceProvider'); to register a different service provider from your own service provider.

tomicakorac's avatar

@MarkRedeman thanks. That much I got, but I see now that my question isn't quite complete.

So I do know that I can register a new service provider with:

$this->app->register('Acme\ServiceProvider');

but I'm not sure where is the best place to put that line. My idea is to create vendor/package/bootstrap/autoload.php, place $this->app->register('Acme\ServiceProvider'); in it, and then autoload that file from the package's composer.json. But autoloading it isn't going to automatically run it on application boot, is it?

1 like
tomicakorac's avatar

@crynobone is that a response to my question? If yes, can you please elaborate on where should I place this: $this->app->register('Acme\ServiceProvider'); to make it automatically register my service provider?

jekinney's avatar

Great post, thank you for sharing!

Depending on the possibly of adding, updating or removing I to don't necessarily put packages in the vender folder. So as a few stated there are different ways of doing it.

Example I have a basic dynamic site structure with front and backend that I use frequently that is to time consuming to fork just for small tweaks. And of course the blog, discussion board etc. But user roles that can get to complicated to change or 99% chance will never change I pull in as a package in the vendor folder.

Ncls's avatar

How do you use dependancies? For example if I want my package to user Intervention Image..? And how can you test this during development?

memovillalobos's avatar

Hey @notflip did you ever manage to find any documentation or help regarding including dependencies during your package development? I can't seem to find a way for my package to find the classes that im requiring with composer... Thank you very much in advance!

christopher's avatar

Didnt found anything on laracast but is there a lesson about package development?

ecomevo's avatar

I've been using the Studio package for development on (currently) private packages. However, we can't include the composer.lock file in git because of the symlinks Studio creates that won't be present on anyone else's machines (including production/staging).

Has anyone found a way to work around this so composer.lock doesn't break things with those machine specific symlinks?

For instance, here is the require block for composer.json:

"require": {
      "php": ">=7.0.0",
      "laravel/framework": "5.2.*",
      "our-repo/our-package": "dev-master",
}

And here is the repositories section necessary to declare the source of the private packages:

"repositories": [
      {
          "type": "git",
          "url": "[email protected]:our-repo/our-package.git"
      },
]

Everything works fine so long as composer.lock is ignored, but rest of the team is pushing to see that changed for consistency sake.

roblesterjr04's avatar

If I were to publish that composer.json file to git as is, wouldn't someone trying to use this package get an error that the packages directory couldn't be found?

I keep seeing people create this packages directory, but the packages directory is not listed in any composer files that i've seen in other packages, so I can assume I need to change it, but nobody has explicitly said that before publishing the package, you have to update your composer.json file. Can I get some clarity on the dev process of packages?

sandervanhooft's avatar

Hi @roblesterjr04,

Did you find a solution yet you care to share? Let me try to answer your question.

I think you are asking a few questions here: a) How can I use packages which are located in a local folder instead of pulled in via packagist? b) Should I change the local package reference when publishing my packages? If so, how? And when? c) What is a nice package development workflow?

So here we go.

For convenience, let's give the packages a name for clarification:

  • ParentPackage: a package you are developing locally and intend to publish to packagist.org ASAP. This package depends on ChildPackage.
  • ChildPackage: a package you are also developing locally and intend to publish to packagist.org ASAP. This package is required by the ParentPackage.

And let's assume you are open sourcing the packages, which means making them resolvable via packagist.org, so you can use composer require <vendor>/<package> to use them.

a) How can I use packages which are located in a local folder instead of pulled in via packagist?

This has been answered before in this thread. The gist of it is to include this in the ParentPackage's composer.json:

"autoload": {
    "psr-4": {
        "App\\": "app/",
        "Vendor\\Package\\": "packages/Vendor/Package/src"
    }
},

And then don't forget to actually require the ChildPackage.

If this doesn't work, check if the ChildPackage's composer name settings (/) correspond with the one you're referencing here in the ParentPackage: "Vendor\\Package\\": "packages/Vendor/Package/src".

b) Should I change the local package reference when publishing my packages? If so, how? And when?

Yes, you should remove the local "repositories" reference from the ParentPackage before publication. Referencing packages locally is only for local development purposes.

But in order for your ParentPackage to keep functioning, it will need the ChildPackage. So you need the ChildPackage to be available via packagist.org.

That's why you publish the ChildPackage to packagist as soon as it is ready.

After that, you prepare the ParentPackage for publication:

  1. remove the references to the ChildPackage from the repositories and the require arrays.
  2. run rm -rf ./vendor in the directory of your ParentPackage folder. This removes all installed.
  3. run composer require <your-child-package-reference-you-can-find-it-on-packagist>
  4. run 'composer install` in the same directory to install all dependencies

Test your ParentPackage to see if all went well.

c) What is a nice package development workflow?

I think I have covered much of it. If you're still stuck with questions, tag me in or send me a PM.

Please or to participate in this conversation.