Courses

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

Publishing Package to Github & Packagist

To make our package available to others, we just need to initialize the Git repository inside our folder of /packages/laraveldaily/laravel-permission-editor and push the code to GitHub, then register that repository on Packagist.

So, step by step.


1. Push to GitHub

First, we create a new repository on GitHub. You can actually use a different system like Gitlab or Bitbucket, just the repository should be public.

Important: to avoid conflicts, the repository name should be exactly the same as you specified in the composer.json of the package, in the "name" field.

Laravel package Github

Then we follow the GitHub instructions to push our code to the repository, just replacing the suggested "readme.md" commit with pushing all files.

cd packages/laraveldaily/laravel-permission-editor
git init
git add .
git commit -m "First commit"
git branch -M main
git remote add origin https://github.com/LaravelDaily/laravel-permission-editor.git
git push -u origin main

This is the result, in Terminal:

Laravel package push terminal

So, our package code is on Github now, great!

Laravel package GitHub pushed


2. Readme file

As you can see in the screenshot above, there are no installation instructions, and even GitHub itself is telling us to create a README file.

Let's be polite to our users and create this file, with installation instructions, in Markdown language, and push it to GitHub. This is the result:

Laravel package readme


3. Version Release on GitHub

We have the package on GitHub, but this is not where composer takes the packages from. The central database of the packages is called Packagist. You need to create the account there, and then Submit your package.

But, before we do that, let's tell Packagist that we're launching our first version, let's assign it a version number of v0.0.1.

In general, if you follow the so-called semantic versioning, those three parts mean this:

  • The first number is the major version: it means big releases with potential breaking changes, like Laravel 9 or Laravel 10, which happens every 6 months
  • The second number is the minor version: it means new features without breaking the full package behavior, like Laravel 9.xx that happens every week
  • The third number is the patch version: it means any bugfixes or small typo fixes which may happen multiple times per day if needed

It's totally your personal preference which version to start from: some creators choose to start with v1.0.0, while others release v0.0.1 and stay on v0.x for months after that.

To release a version, we need to do two things.

First, in the composer.json of our package, we need to specify the version and push that change to GitHub:

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

{
"name": "laraveldaily/laravel-permission-editor",
"description": "Visual UI for managing Roles/Permissions for Spatie Laravel Permission package",
 
// ...
 
"version": "0.0.1"
}

Next, we need to go to GitHub and look at the "Releases" on the right side, and click "Create a new release":

Laravel package new release

Inside that form, we need to create a new tag corresponding to our version number:

Laravel package new release tag

Finally, we can put the name and the description of the new version, which would be easily visible to the package users.

Laravel package new release description

Feel free to put any text you want in there, and click "Publish release".

Laravel package first release


4. Release on Packagist

As I mentioned before, we need to publish the package on Packagist.

The direct URL to submit the package is this: packagist.org/packages/submit

Laravel package packagist submit

As you can see, all we need to do is provide the repository URL from Github. Packagist will "scan" the contents of that repository and check if everything needed is present for the release.

So I put this: https://github.com/LaravelDaily/laravel-permission-editor

Then I get this text as a result:

The package name found for your repository is: laraveldaily/laravel-permission-editor, press Submit to confirm.

And I click "Submit"...

First, the package will be crawled, and then the information update will happen, and in a minute or so, I see THIS:

Laravel package released

That's it! We released our package to the public!

Hard to believe? Let's test it! Let's create a new fresh Laravel project, install the Spatie Permission package, and install our package.

laravel new project5
cd project5
composer require spatie/laravel-permission
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan migrate
composer require laraveldaily/laravel-permission-editor
php artisan vendor:publish --provider="Laraveldaily\LaravelPermissionEditor\PermissionEditorServiceProvider"

Launching the browser...

Laravel package working

Ta-daaaa!

So, that's it for this long tutorial, this is how to create and publish a Laravel package. As always, if you have any questions or see some information missing, shoot in the comments below.

The package repository is available on GitHub: LaravelDaily/laravel-permission-editor

See you guys in other tutorials!

avatar

Image is missing in the following line:

This is the result, in Terminal:

👍 1
avatar

Thanks for the notice, fixed!

avatar
You can use Markdown
avatar

Struggled a bit following the tutorial in places, but with some determination and lots of faff I actually released my first ever Laravel package! It won't set the world alight, but it will let you generate website thumbnails using the url2png API :) Feel free to have & any offer any recommendations :) https://github.com/gkimpson/url2png-laravel https://packagist.org/packages/gkimpson/url2png-laravel

avatar

Looks like a great start! Happy to inspire your journey to create packages. Could you speciffy the places where you struggled, maybe I could change something in the course material to be clearer?

avatar

It was probably more to do with me doing new concepts than anything you did wrong - although one part of chapter 5 - the PermissionEditorServiceProvider.php boot() method changes somewhat (the ->as('permission-editor'); is removed for instance - after a while I realised this is needed. It was still a very good tutorial and the final chapter with the information regarding the releasing the packages was super useful as this was a first for me :)

I think a good way would be to do a very basic package initially & then have this permissions-editor package as a more advanced package (as its involves other dependencies, routes, views etc..), similar to how you have done the Laravel Testing in two courses (one for beginners and one advanced).

Either way, I did a thing and made a package for the first time so i'm happy with that :) Keep up the good work Povilas!

avatar

Thanks again for the feedback, will keep in mind!

avatar
You can use Markdown
avatar

Thank you so much That's very helpful

avatar
You can use Markdown
avatar

I was trying to find a package development tutorial that will explain about dependencies and how to inlude them into my own package. Finally I found it here.

Thanks a lot Povilas.

Looking forward for new article based tutorials Like these as these save a lot of time.

avatar
You can use Markdown
avatar

Of several that I have tried, this is the first course through which I have been able to completely create a package to be able to reuse my code.

Very good material, thanks for the effort.

👍 2
avatar
You can use Markdown
avatar

so should we install our package dependencies like spati-permissions, before install our package ?

can we just dirctly install our package with it dependencies ?

thank you mr Povilas

avatar

You can set dependancies in your packages composer.json file. This will install the dependancies with your package at the same time. No need to install it separate

avatar

Hey Mr.Modestas, so what if i publish new package depends on another packages with spesfic versions maybe......

can i let the end user when install my package download all dependencies of my package with right versions dirctly without write them on composer.json by him and without install them by him ?

because maybe the end user install wrong version, or maybe even don't relize that my package depends on another packages

avatar

All the packages and versions you define in your composer.json as dependancies - will be installed. These will be exact versions you need and it will not allow users to have the same package with higher/lower versions (will trigger composer incompatibility error)

avatar

Great!

Thank you so much Mr.Modestas

avatar
You can use Markdown
avatar

Hi Povilas, congratulations to you and your team for this great tutorial.

I was wondering if the github repository has to be public in order to publish it in packagist. What if I have a modular application that works with multiple packages thatn can be optionally installed and those packages work only for that particular app? For example the main application has its core module that could be cloned from github, but then you could install other modules by requiring packages.

Since this packages only work with the core module, can they be a sort of private packages?

avatar

In case you need private packages (which it sounds that you do) - you need to use private packagist:

https://packagist.com/

avatar
You can use Markdown
avatar
You can use Markdown