Courses

How to Create Laravel Package: Step-by-Step Example

Create Package: Structure & composer.json

There are a few ways to start developing the package, there are a few popular skeleton repositories like this one from Spatie.

But for this particular tutorial, I want to explain how it all works inside, so you may use skeletons for your future packages, but not the first one.

What I'm suggesting for the beginning is that we create a new Laravel project (not a package), and then we will "fit" our package inside of it, as a subfolder, "faking" it to work via composer.

  • Create a new Laravel project with laravel new project (or another command if you prefer)
  • Inside that project, create a folder /packages/laraveldaily/laravel-permission-editor

This is exactly what I will call our package. The name of the package consists of two parts: vendor/package-name, so our vendor (creator) is laraveldaily (a real username on GitHub) and the actual package will be called laravel-permission-editor.

Laravel package folder

Next, we need to create or generate a composer.json file in the main folder of our package. Composer has a command for that composer init which will launch a wizard with a set of questions that we just answer, and then it generates the composer.json file.

cd packages/laraveldaily/laravel-permission-editor
composer init

To be honest, it doesn't matter that much what you will specify in that composer wizard because you would be able to easily change everything later. It will matter when publishing the package, so we will re-review this file much later, anyway.

For now, I will start with these values:

packages/laraveldaily/laravel-permission-editor/composer.json:

{
"name": "laraveldaily/laravel-permission-editor",
"description": "Visual UI for managing Roles/Permissions for Spatie Laravel Permission package",
"license": "MIT",
"authors": [
{
"name": "Povilas Korop",
"email": "povilas@laraveldaily.com"
}
],
"minimum-stability": "dev",
"require": {}
}

Next, we need to load that package into our main composer.json file, the one that is in the Laravel project and not in the packages/ folder.

We add the package with the dev-main branch as a requirement:

composer.json

// ...
"require": {
"php": "^8.0.2",
"guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^9.19",
"laravel/sanctum": "^3.0",
"laravel/tinker": "^2.7",
"laraveldaily/laravel-permission-editor": "dev-main"
},
"repositories": [
{
"type": "path",
"url": "packages/laraveldaily/laravel-permission-editor",
"options": {
"symlink": true
}
}
],

And we run composer update in our main project. Would it find our package?

In case of success, among the update lines, you should see this one:

  • Installing laraveldaily/laravel-permission-editor (dev-main): Symlinking from packages/laraveldaily/laravel-permission-editor

Great, so our Laravel project sees the package now! We can start working on the functionality.

avatar

Your requirements could not be resolved to an installable set of packages.

Problem 1 > - Root composer.json requires MYPACKAGENAME, it could not be found in any version, there may be a typo in the package name.

I think, that at this step it should be pushed to packagist/github ? Otherwise "composer update" is throwing that error..

Thank you!

avatar

No, for me it worked from local computer, I pushed to packagist/github only in the last steps. Double check my example and your code for any typos.

avatar

Thank you. I have missed most important part :-) . now it works.

"repositories": [ { "type": "path", "url": "packages/laraveldaily/laravel-permission-editor", "options": { "symlink": true } } ],

avatar

Hello all, For some reason when I use "url": "packages/laraveldaily/laravel-permission-editor" the composer return this error The url supplied for the path (packages/laraveldaily/laravel-permission-editor) repository does not exist Then I put entire path like as /home/myuser/project/packages/laraveldaily/laravel-permission-editor and it's worked like a charm. PS. Laravel 10.14.1 Composer 2.5.5

avatar

Maybe your web-server is configured in a way that those URLs are misunderstood differently? Maybe try with slash? "/packages/laraveldaily/laravel-permission-editor"?

avatar

I tried that way too, and it didn't work. For now I'm happy with the result, but I'm going to try to understand why I had to use the full fit.

avatar

Sir,

Can we use laravel packages as laravel microservices architecture moduler design or any other better way to implement moduler in laravel?

avatar

I haven't worked with microservices personally, so I can't really tell. For modular structure in the same project, I would recommend nWidart/laravel-modules package. But if you want modules to be reused in multiple projects, then probably packages is the best way.

avatar

What about using .gitmodules https://git-scm.com/docs/gitmodules? With use with PHPStorm VersionControl > Directory Mappings that works OK, and also committing several modules at once