Creating Laravel Package from Scratch

Photo by from Pexels

re you a developer? If yes, I’m sure that you must always add some packages/libraries to your project. I’m a Laravel developer, maybe you too. And inside Laravel, we have so many useful packages that ready to use, make life easier for us. What do you need? Do you want an API Authentication? You have Laravel Passport/Sanctum. Need a monitoring queue job? You have Horizon. Or maybe other packages from other developers/companies like Spatie Laravel Permission for managing roles and permissions. And trust me, there are so many more packages that useful for our projects. Just a little tip from me, if you want to build something for your client/company’s need, maybe it’s best for you to find first the package that fulfills your needs. If there is, then you save your time and enjoy.

But, what if there are no packages out there that fulfill your needs? Or maybe you’re already built something right now and think that maybe your works are worth it to be available publicly as a package. So that, people, or even yourselves, can reuse your package. I’ve built a lot of websites using Laravel, and sometimes I always create the same functions/classes same and same again in different projects. Maybe you feel that way too, the same way I feel. It’s better if we convert our functions/classes to a package then we can install it wherever we want.

So in this article, I’ll show you how to build a package for Laravel from scratch. Yeah, you read it, from scratch without any package helper. Why do we want to build something without a package helper? Because it’s simple and, trust me, if we build something from scratch, we’ll know more about how a package works. The more we know how it works, the more we can deeply understand and explore by ourselves. Ok? Let’s get going!

Content Overview

  • Our Goals
  • Package Scaffolding
  • Class and Facade
  • Installing the Package
  • Time to Test
  • Publish Your Package to Github

#1 Our Goals

What we’ll do in this article? Very simple, create a simple package, upload it to your Github, then install it everywhere in your Laravel projects. I won’t show you how to publish your package to Packagist (PHP Package Repository), but there’s a reference on how to do it. But it’s enough for you to start with developing a simple package that you can install everywhere.

What package function that we create right now? It’s a very simple package with ping() function inside that returns a “pong” message. But trust me, if you know how to do it, you can do more than we do today.

Photo by Gia Oris on Unsplash

#2 Package Scaffolding

First thing first, we want to test the package too right? So we need a fresh installation Laravel project or you can use an existing one. To install a fresh Laravel project, as usual, you can use this command:

composer create-project laravel/laravel --prefer-dist laravel-package

After you have the project, then we can create a package inside the project. In the root folder of your project, create a folder with these folder structures:

-- Vendor
-- Package Name
-- src

In our tutorial now, the tree structure will be like this:

Image 1. Package Scaffolding

What I create is a package with my name as a vendor, followed by a package name that we name it “Ping”. Inside it, we have an src folder. Of course, you don’t have to use my name as a vendor, and you can create whatever package name you want.

Then, using the terminal, cd (change directory) to packages/Cerwyn/Ping and type this:

composer init

What composer init do? It generates composer.json automatically for you.

Image 2. Composer Init

After successfully initiate the composer, the composer.json will automatically be created with the information you typed before.

Image 3. Composer Json for Package

#3 Class and Facade

The next thing to do, we need to create a simple class/function to test that our package works. I’ve mentioned above that we’ll create a ping() function that will return a “pong” message. Let’s create a class first.

Inside the src folder, create Ping.php class.


To call our Ping class, it’ll be easier if we use the Facades. Let’s create a new folder inside the src name Facades, then a PingFacade.php inside.


The last thing to do, we need a service provider. If you’re not familiar with a service provider, it’s an essential part when developing a package. You can see the detailed explanations in this reference. For a short recap, if you want to register a route, event listeners, middleware, view, etc you must make a change in the service provider. For now, we’ll use this to register our class into a service container. You’ll see later how this thing works.

Let’s create a PackageServiceProvider.php inside the src folder and type this.


To automatically register our package with a Laravel project using Laravel’s package auto-discovery, we need to modify the composer.json of the package (not the composer.json in the Laravel project).

Image 4. Package’s composer.json

As you can see in the image above, we add an extra object with providers and aliases inside. Again, if you create a different vendor or package name, you need to adjust it.

In the end, the package structure will be like this.

Image 5. Final Package Scaffolding

#4 Installing the Package

It’s time for us to try the package. First, don’t confuse here. We have 2 composer.json files here, the composer.json for the package itself and for the Laravel project. Before installing the package into our Laravel project, open the project’s composer.json, and add this repository object.

Image 6. Project’s composer.json

On line 70, the type of the repository must be a path because we load the package from the local memory. And the url must point to your package folder.

Note here: You can develop the package everywhere, not always inside the Laravel project. But in this step, you must adjust the url to where your package lives.

Then after you modify the composer.json, update your composer first.

composer update

Then install your package.

composer require Cerwyn/Ping

Until this step, your package should be installed successfully. Let me know in the comment below if your installation failed.

#5 Time to Test

Is our package works? Let’s test it. I’m a fan of tinker so I’ll test the package using the tinker.

Image 7. Test using Tinker

If you want to use another method to test, go ahead. You can try using the facades to call the function. But from the tinker test above, I see a successful message “pong” that indicates our package works.

#6 Publish Your Package to Github

You must know that in order for your package publicly available, you must publish it to the Packagist. But of course, you can use Github too, but with an additional effort. I’ll show you what I mean by that.

In your terminal, cd (change directory) to your package lives, git init then push to your Github repository. So your project in Github will be like this:

Image 8. Publishing to Github

The question is, how can I fetch my package that lives in Github? This is what I mean by an additional effort. It’s not publicly available, so you can’t just type “composer require” and expecting your package will be installed. Instead, in your composer.json project, you need to add this repository.

Image 9. Importing Package from Github

As you can see, in the repositories object, the type must be “git” and the url is your Github repository URL. Don’t forget to composer update first after modifying the composer.json, then install it as usual.

composer require Cerwyn/Ping

That’s it! It’s a pretty straightforward thing to do for your (maybe) first project to create a package! Congratulations! And bear in mind, there are a lot of things to learn when it comes to creating a package. But you’re not alone. You can refer to this reference/documentation that is well built for package development. Of course, there are rules/best practices you need to follow to build a such good package.

In the end, thanks for reading! I hope this article can be your first step to become a successful Laravel developer. I hope you can build your own open-source project :) see ya.

PHP/Backend Engineer at Undercurrent Capital Pte Ltd — Data Science Enthusiast